<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
<head>
  <meta charset="utf-8" />
  <meta name="generator" content="pandoc" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
  <meta name="description" content="TR-369 – The User Services Platform:
A standardized protocol to manage, monitor, update, and control
connected devices, IoT endpoints, user services and home networks" />
  <title>BBF – TR-369 – The User Services Platform</title>
  <style>
    code{white-space: pre-wrap;}
    span.smallcaps{font-variant: small-caps;}
    div.columns{display: flex; gap: min(4vw, 1.5em);}
    div.column{flex: auto; overflow-x: auto;}
    div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
    /* The extra [class] is a hack that increases specificity enough to
       override a similar rule in reveal.js */
    ul.task-list[class]{list-style: none;}
    ul.task-list li input[type="checkbox"] {
      font-size: inherit;
      width: 0.8em;
      margin: 0 0.8em 0.2em -1.6em;
      vertical-align: middle;
    }
    .display.math{display: block; text-align: center; margin: 0.5rem auto;}
    /* CSS for citations */
    div.csl-bib-body { }
    div.csl-entry {
      clear: both;
    }
    .hanging-indent div.csl-entry {
      margin-left:2em;
      text-indent:-2em;
    }
    div.csl-left-margin {
      min-width:2em;
      float:left;
    }
    div.csl-right-inline {
      margin-left:2em;
      padding-left:1em;
    }
    div.csl-indent {
      margin-left: 2em;
    }  </style>
  <link rel="stylesheet" href="bbf.css" />
  <link rel="stylesheet" href="extra.css" />
  <link rel="stylesheet" href="release.css" />
  <link rel="stylesheet" href="toc.css" />
  <link rel="stylesheet" href="local.css" />
  <!-- Automatic hover links scripts -->
  <script>
  window.addEventListener('DOMContentLoaded', function() {
    var hoverlink = null;

    var elems = document.querySelectorAll('.auto-hoverlink:not(section)');
      for (var i = 0; i < elems.length; i++) {
        var elem = elems[i];

        elem.addEventListener('mouseenter', event => {
          var target = event.target;
          var info_attr = target.attributes.getNamedItem('data-info');
          var anchor_attr = target.attributes.getNamedItem('data-anchor');
          var thing = info_attr ? info_attr.value : target.localName
          /* we check the parent to cover the case where pandoc has moved the
             id from a header to its parent section */
          var anchor = target.id || target.parentElement.id ||
                                    (anchor_attr ? anchor_attr.value : null);

          if (hoverlink) {
            hoverlink.remove();
            hoverlink = null;
          }

          if (!anchor) {
              console.warn('%s %s has no id or data-anchor',
                           thing, target.textContent);
          } else {
            hoverlink = document.createElement('a');
            hoverlink.href = '#' + anchor;
            hoverlink.className = 'hoverlink';
            hoverlink.title = 'Permalink to this ' + thing;
            target.appendChild(hoverlink);
          }
        });

        elem.addEventListener('mouseleave', () => {
          if (hoverlink) {
            setTimeout(function(href) {
              if (hoverlink && hoverlink.href == href) {
                hoverlink.remove();
                hoverlink = null;
              }
            }, 1000, hoverlink.href);
          }
        });
      }
  });
  </script>
  <!-- Automatic hover links styles -->
  <style>
  :root {
      --hoverlink-gap: 0.2em;
      --hoverlink-size: 0.9em;
  }

  .hoverlink {
      text-decoration: none;
  }

  .hoverlink::after {
      position: absolute;
      display: inline-block;
      content: "";
      margin-left: var(--hoverlink-gap);
      width: var(--hoverlink-size);
      height: var(--hoverlink-size);
      background-size: var(--hoverlink-size) var(--hoverlink-size);
      /* https://icon-library.com/images/permalink-icon/permalink-icon-17.jpg
         (resized from 512x512 to 64x64) */
      background-image: url(permalink.png);
  }
  </style>
  <!--[if lt IE 9]>
    <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
  <![endif]-->
</head>
<body>
<div class="main-content">
<header id="title-block-header">
<h1 class="title auto-hoverlink" id="title">TR-369 – The User Services
Platform</h1>
<p class="subtitle">Issue: 1 Amendment 3 Corrigendum 1 <span
class="release"></span></p>
<p class="date">Issue Date: October 2023</p>
</header>
<nav id="SIDEBAR" role="doc-toc">
<ul>
<li><a href="#sec:introduction" id="toc-sec:introduction">1
Introduction</a>
<ul>
<li><a href="#sec:executive-summary" id="toc-sec:executive-summary">1.1
Executive Summary</a></li>
<li><a href="#sec:purpose-and-scope" id="toc-sec:purpose-and-scope">1.2
Purpose and Scope</a></li>
<li><a href="#sec:references-and-terminology"
id="toc-sec:references-and-terminology">1.3 References and
Terminology</a></li>
<li><a href="#sec:definitions" id="toc-sec:definitions">1.4
Definitions</a></li>
<li><a href="#sec:abbreviations" id="toc-sec:abbreviations">1.5
Abbreviations</a></li>
<li><a href="#sec:specification-impact"
id="toc-sec:specification-impact">1.6 Specification Impact</a></li>
</ul></li>
<li><a href="#sec:architecture" id="toc-sec:architecture">2
Architecture</a>
<ul>
<li><a href="#sec:endpoints" id="toc-sec:endpoints">2.1
Endpoints</a></li>
<li><a href="#sec:endpoint-identifier"
id="toc-sec:endpoint-identifier">2.2 Endpoint Identifier</a></li>
<li><a href="#sec:service-elements" id="toc-sec:service-elements">2.3
Service Elements</a></li>
<li><a href="#sec:data-models" id="toc-sec:data-models">2.4 Data
Models</a></li>
<li><a href="#sec:path-names" id="toc-sec:path-names">2.5 Path
Names</a></li>
<li><a href="#sec:other-path-decorators"
id="toc-sec:other-path-decorators">2.6 Other Path Decorators</a></li>
<li><a href="#sec:data-model-path-grammar"
id="toc-sec:data-model-path-grammar">2.7 Data Model Path
Grammar</a></li>
</ul></li>
<li><a href="#sec:discovery" id="toc-sec:discovery">3 Discovery and
Advertisement</a>
<ul>
<li><a href="#sec:controller-information"
id="toc-sec:controller-information">3.1 Controller Information</a></li>
<li><a href="#sec:required-agent-information"
id="toc-sec:required-agent-information">3.2 Required Agent
Information</a></li>
<li><a href="#sec:using-dhcp" id="toc-sec:using-dhcp">3.3 Use of DHCP
for Acquiring Controller Information</a></li>
<li><a href="#sec:gatewayinfo" id="toc-sec:gatewayinfo">3.4 Use of DHCP
for Exchanging GatewayInfo</a></li>
<li><a href="#sec:using-mdns" id="toc-sec:using-mdns">3.5 Using
mDNS</a></li>
<li><a href="#sec:using-dns" id="toc-sec:using-dns">3.6 Using
DNS</a></li>
<li><a href="#sec:dns-sd-records" id="toc-sec:dns-sd-records">3.7 DNS-SD
Records</a></li>
<li><a
href="#sec:using-the-sendonboardrequest-operation-and-onboardrequest-notification"
id="toc-sec:using-the-sendonboardrequest-operation-and-onboardrequest-notification">3.8
Using the SendOnBoardRequest() operation and OnBoardRequest
notification</a></li>
</ul></li>
<li><a href="#sec:mtp" id="toc-sec:mtp">4 Message Transfer Protocols</a>
<ul>
<li><a href="#sec:generic-requirements"
id="toc-sec:generic-requirements">4.1 Generic Requirements</a></li>
<li><a href="#sec:coap-binding-obsoleted"
id="toc-sec:coap-binding-obsoleted">4.2 CoAP Binding
(OBSOLETED)</a></li>
<li><a href="#sec:websocket" id="toc-sec:websocket">4.3 WebSocket
Binding</a></li>
<li><a href="#sec:stomp-binding" id="toc-sec:stomp-binding">4.4 STOMP
Binding</a></li>
<li><a href="#sec:mqtt-binding" id="toc-sec:mqtt-binding">4.5 MQTT
Binding</a></li>
<li><a href="#sec:unix-domain-socket"
id="toc-sec:unix-domain-socket">4.6 UNIX Domain Socket Binding</a></li>
</ul></li>
<li><a href="#sec:encoding" id="toc-sec:encoding">5 Message Encoding</a>
<ul>
<li><a href="#sec:parameter-value-encoding"
id="toc-sec:parameter-value-encoding">5.1 Parameter and Argument Value
Encoding</a></li>
</ul></li>
<li><a href="#sec:e2e-message-exchange"
id="toc-sec:e2e-message-exchange">6 End to End Message Exchange</a>
<ul>
<li><a href="#sec:exchange-of-usp-records-within-an-e2e-session-context"
id="toc-sec:exchange-of-usp-records-within-an-e2e-session-context">6.1
Exchange of USP Records within an E2E Session Context</a></li>
<li><a
href="#sec:exchange-of-usp-records-without-an-e2e-session-context"
id="toc-sec:exchange-of-usp-records-without-an-e2e-session-context">6.2
Exchange of USP Records without an E2E Session Context</a></li>
<li><a href="#sec:validating-the-integrity-of-the-usp-record"
id="toc-sec:validating-the-integrity-of-the-usp-record">6.3 Validating
the Integrity of the USP Record</a></li>
<li><a href="#sec:secure-message-exchange"
id="toc-sec:secure-message-exchange">6.4 Secure Message
Exchange</a></li>
</ul></li>
<li><a href="#sec:messages" id="toc-sec:messages">7 Messages</a>
<ul>
<li><a href="#sec:encapsulation-in-a-usp-record"
id="toc-sec:encapsulation-in-a-usp-record">7.1 Encapsulation in a USP
Record</a></li>
<li><a href="#sec:requests-responses-and-errors"
id="toc-sec:requests-responses-and-errors">7.2 Requests, Responses and
Errors</a></li>
<li><a href="#sec:message-structure" id="toc-sec:message-structure">7.3
Message Structure</a></li>
<li><a href="#sec:creating-updating-and-deleting-objects"
id="toc-sec:creating-updating-and-deleting-objects">7.4 Creating,
Updating, and Deleting Objects</a></li>
<li><a href="#sec:reading-an-agents-state-and-capabilities"
id="toc-sec:reading-an-agents-state-and-capabilities">7.5 Reading an
Agent’s State and Capabilities</a></li>
<li><a href="#sec:notifications-and-subscriptions"
id="toc-sec:notifications-and-subscriptions">7.6 Notifications and
Subscription Mechanism</a></li>
<li><a href="#sec:defined-operations-mechanism"
id="toc-sec:defined-operations-mechanism">7.7 Defined Operations
Mechanism</a></li>
<li><a href="#sec:error-codes" id="toc-sec:error-codes">7.8 Error
Codes</a></li>
</ul></li>
<li><a href="#sec:auth" id="toc-sec:auth">8 Authentication and
Authorization</a>
<ul>
<li><a href="#sec:authentication-1" id="toc-sec:authentication-1">8.1
Authentication</a></li>
<li><a href="#sec:rbac" id="toc-sec:rbac">8.2 Role Based Access Control
(RBAC)</a></li>
<li><a href="#sec:trusted-certificate-authorities"
id="toc-sec:trusted-certificate-authorities">8.3 Trusted Certificate
Authorities</a></li>
<li><a href="#sec:trusted-brokers" id="toc-sec:trusted-brokers">8.4
Trusted Brokers</a></li>
<li><a href="#sec:self-signed-certificates"
id="toc-sec:self-signed-certificates">8.5 Self-Signed
Certificates</a></li>
<li><a href="#sec:agent-authentication"
id="toc-sec:agent-authentication">8.6 Agent Authentication</a></li>
<li><a href="#sec:challenge-strings-and-images"
id="toc-sec:challenge-strings-and-images">8.7 Challenge Strings and
Images</a></li>
<li><a href="#sec:analysis-controller-certificates"
id="toc-sec:analysis-controller-certificates">8.8 Analysis of Controller
Certificates</a></li>
<li><a href="#sec:theory-of-operations"
id="toc-sec:theory-of-operations">8.9 Theory of Operations</a></li>
</ul></li>
<li><a href="#sec:bulk-data-collection"
id="toc-sec:bulk-data-collection">Annex A: Bulk Data Collection</a>
<ul>
<li><a href="#sec:introduction-1" id="toc-sec:introduction-1">A.1
Introduction</a></li>
<li><a href="#sec:http-bulk-data-collection"
id="toc-sec:http-bulk-data-collection">A.2 HTTP Bulk Data
Collection</a></li>
<li><a href="#sec:mqtt-bulk-data-collection"
id="toc-sec:mqtt-bulk-data-collection">A.3 MQTT Bulk Data
Collection</a></li>
<li><a href="#sec:uspeventnotif-bulk-data-collection"
id="toc-sec:uspeventnotif-bulk-data-collection">A.4 USPEventNotif Bulk
Data Collection</a></li>
<li><a
href="#sec:using-wildcards-to-reference-object-instances-in-the-report"
id="toc-sec:using-wildcards-to-reference-object-instances-in-the-report">A.5
Using Wildcards to Reference Object Instances in the Report</a></li>
<li><a href="#sec:using-alternative-names-in-the-report"
id="toc-sec:using-alternative-names-in-the-report">A.6 Using Alternative
Names in the Report</a></li>
<li><a href="#sec:encoding-of-bulk-data"
id="toc-sec:encoding-of-bulk-data">A.7 Encoding of Bulk Data</a></li>
</ul></li>
<li><a href="#sec:software-module-management"
id="toc-sec:software-module-management">Appendix I: Software Module
Management</a>
<ul>
<li><a href="#sec:lifecycle-management"
id="toc-sec:lifecycle-management">I.1 Lifecycle Management</a></li>
<li><a href="#sec:software-modules" id="toc-sec:software-modules">I.2
Software Modules</a></li>
<li><a href="#sec:execution-environment-concepts"
id="toc-sec:execution-environment-concepts">I.3 Execution Environment
Concepts</a></li>
<li><a href="#sec:fault-model" id="toc-sec:fault-model">I.4 Fault
Model</a></li>
</ul></li>
<li><a href="#sec:firmware-management-of-devices-with-usp-agents"
id="toc-sec:firmware-management-of-devices-with-usp-agents">Appendix II:
Firmware Management of Devices with USP Agents</a>
<ul>
<li><a href="#sec:getting-the-firmware-image-onto-the-device"
id="toc-sec:getting-the-firmware-image-onto-the-device">II.1 Getting the
firmware image onto the device</a></li>
<li><a href="#sec:using-multiple-firmware-images"
id="toc-sec:using-multiple-firmware-images">II.2 Using multiple firmware
images</a></li>
</ul></li>
<li><a href="#sec:device-proxy" id="toc-sec:device-proxy">Appendix III:
Device Proxy</a></li>
<li><a href="#sec:communications-proxying"
id="toc-sec:communications-proxying">Appendix IV: Communications
Proxying</a>
<ul>
<li><a href="#sec:proxying-building-block-functions"
id="toc-sec:proxying-building-block-functions">IV.1 Proxying Building
Block Functions</a></li>
<li><a href="#sec:discovery-proxy" id="toc-sec:discovery-proxy">IV.2
Discovery Proxy</a></li>
<li><a href="#sec:connectivity-proxy"
id="toc-sec:connectivity-proxy">IV.3 Connectivity Proxy</a></li>
<li><a href="#sec:message-transfer-protocol-mtp-proxy"
id="toc-sec:message-transfer-protocol-mtp-proxy">IV.4 Message Transfer
Protocol (MTP) Proxy</a></li>
<li><a href="#sec:usp-to-non-usp-proxy"
id="toc-sec:usp-to-non-usp-proxy">IV.5 USP to Non-USP Proxy</a></li>
</ul></li>
<li><a href="#sec:iot-data-model-theory-of-operation"
id="toc-sec:iot-data-model-theory-of-operation">Appendix V: IoT Data
Model Theory of Operation</a>
<ul>
<li><a href="#sec:introduction-2" id="toc-sec:introduction-2">V.1
Introduction</a></li>
<li><a href="#sec:iot-data-model-overview"
id="toc-sec:iot-data-model-overview">V.2 IoT data model
overview</a></li>
<li><a href="#sec:architecture-mappings"
id="toc-sec:architecture-mappings">V.3 Architecture mappings</a></li>
<li><a href="#sec:iot-data-model-object-details"
id="toc-sec:iot-data-model-object-details">V.4 IoT data model Object
details</a></li>
<li><a href="#sec:examples" id="toc-sec:examples">V.5 Examples</a></li>
</ul></li>
<li><a href="#sec:software-modularization-theory-of-operations"
id="toc-sec:software-modularization-theory-of-operations">Appendix VI:
Software Modularization and USP-Enabled Applications Theory of
Operation</a>
<ul>
<li><a href="#sec:background" id="toc-sec:background">VI.1
Background</a></li>
<li><a href="#sec:basic-solution-concepts"
id="toc-sec:basic-solution-concepts">VI.2 Basic Solution
Concepts</a></li>
<li><a href="#sec:usp-service-use-cases"
id="toc-sec:usp-service-use-cases">VI.3 USP Service Use Cases</a></li>
<li><a href="#sec:usp-broker-responsibilities"
id="toc-sec:usp-broker-responsibilities">VI.4 USP Broker
Responsibilities</a></li>
<li><a
href="#sec:data-model-implications-for-usp-brokers-and-usp-services"
id="toc-sec:data-model-implications-for-usp-brokers-and-usp-services">VI.5
Data Model Implications for USP Brokers and USP Services</a></li>
<li><a href="#sec:startup-and-shutdown-procedures"
id="toc-sec:startup-and-shutdown-procedures">VI.6 Startup and Shutdown
Procedures</a></li>
<li><a href="#sec:usp-services-and-software-modules"
id="toc-sec:usp-services-and-software-modules">VI.7 USP Services and
Software Modules</a></li>
</ul></li>
</ul>
</nav>
<h3 class="unnumbered unlisted auto-hoverlink" data-info="header"
id="list-of-figures">List of Figures</h3>
<ol>
<li><a href="#fig:usp-agent-and-controller-architecture">USP Agent and
Controller Architecture</a></li>
<li><a href="#fig:receiving-a-x509-certificate">Receiving a X.509
Certificate</a></li>
<li><a href="#fig:usp-request-response-over-coap">Example: USP
Request/Response over the CoAP MTP</a></li>
<li><a href="#fig:websocket-session-handshake">WebSocket Session
Handshake</a></li>
<li><a href="#fig:usp-request-using-a-websocket-session">USP Request
using a WebSocket Session</a></li>
<li><a href="#fig:usp-over-stomp">USP over STOMP Architecture</a></li>
<li><a href="#fig:usp-over-mqtt">USP over MQTT Architecture</a></li>
<li><a href="#fig:mqtt-packets">MQTT Packets</a></li>
<li><a href="#fig:unix-domain-socket-binding">Unix Domain Socket
Binding</a></li>
<li><a href="#fig:unix-domain-socket-frame-with-handshake-message">UNIX
Domain Socket Frame with Handshake Message</a></li>
<li><a href="#fig:unix-domain-socket-frame-with-usp-record-message">UNIX
Domain Socket Frame with USP Record Message</a></li>
<li><a href="#fig:processing-received-records">Processing of Received
USP Records</a></li>
<li><a href="#fig:segmentation-and-reassembly">E2E Segmentation and
Reassembly</a></li>
<li><a href="#fig:handshake">TLS Session Handshake</a></li>
<li><a href="#fig:a-successful-requestresponse-sequence">A successful
request/response sequence</a></li>
<li><a href="#fig:a-failed-requestresponse-sequence">A failed
request/response sequence</a></li>
<li><a
href="#fig:operate-message-flow-for-synchronous-operations">Operate
Message Flow for Synchronous Operations</a></li>
<li><a
href="#fig:operate-message-flow-for-asynchronous-operations">Operate
Message Flow for Asynchronous Operations</a></li>
<li><a href="#fig:receive-record">Receiving a USP Record</a></li>
<li><a href="#fig:no-secure-message-exchange">USP Record without USP
Layer Secure Message Exchange</a></li>
<li><a href="#fig:send-record">Sending a USP Record</a></li>
<li><a href="#fig:check-cert">Checking a Certificate</a></li>
<li><a href="#fig:determine-role">Determining the Role</a></li>
<li><a href="#fig:broker-with-received-record">Trusted Broker with
Received Record</a></li>
<li><a href="#fig:broker-with-sent-record">Trusted Broker Sending a
Record</a></li>
<li><a href="#fig:deployment-unit-state-diagram">Deployment Unit State
Diagram</a></li>
<li><a href="#fig:execution-unit-state-diagram">Execution Unit State
Diagram</a></li>
<li><a href="#fig:multi-exec-env">Possible Multi-Execution Environment
Implementation</a></li>
<li><a href="#fig:execution-environment-state-diagram">Execution
Environment State Diagram</a></li>
<li><a
href="#fig:example-of-mtp-proxy-in-lan-with-wan-controller">Example of
MTP Proxy in LAN with WAN Controller</a></li>
<li><a href="#fig:coap-stomp-mtp-proxy-example-flow">CoAP-STOMP MTP
Proxy Example Flow</a></li>
<li><a href="#fig:iot-data-model">IoT Data Model</a></li>
<li><a href="#fig:iot-individual-device-models">IoT individual device
models</a></li>
<li><a href="#fig:iot-proxied-device-model">IoT proxied device
model</a></li>
<li><a href="#fig:iot-threshold-trigger-sensitivity">IoT threshold
trigger sensitivity</a></li>
<li><a href="#fig:iot-threshold-trigger-hold-time">IoT threshold trigger
hold time</a></li>
<li><a href="#fig:iot-threshold-trigger-rest-time">IoT threshold trigger
rest time</a></li>
<li><a href="#fig:iot-threshold-trigger-minimum-duration">IoT threshold
trigger minimum duration</a></li>
<li><a href="#fig:software-modularization-use-cases">Software
Modularization Use Cases</a></li>
</ol>
<h3 class="unnumbered unlisted auto-hoverlink" data-info="header"
id="list-of-tables">List of Tables</h3>
<ol>
<li><a href="#tbl:proxy-building-block-functions">Proxy Building Block
Functions</a></li>
<li><a href="#tbl:possible-mtp-proxy-methods">Possible MTP Proxy
Methods</a></li>
</ol>
<h3 class="unnumbered unlisted new-page auto-hoverlink"
data-info="header" id="sec:notice">Notice</h3>
<p>The Broadband Forum is a non-profit corporation organized to create
guidelines for broadband network system development and deployment. This
Technical Report has been approved by members of the Forum. This
Technical Report is subject to change. This Technical Report is owned
and copyrighted by the Broadband Forum, and all rights are reserved.
Portions of this Technical Report may be owned and/or copyrighted by
Broadband Forum members.</p>
<h3 class="unnumbered unlisted auto-hoverlink" data-info="header"
id="sec:intellectual-property">Intellectual Property</h3>
<p>Recipients of this Technical Report are requested to submit, with
their comments, notification of any relevant patent claims or other
intellectual property rights of which they may be aware that might be
infringed by any implementation of this Technical Report, or use of any
software code normatively referenced in this Technical Report, and to
provide supporting documentation.</p>
<h3 class="unnumbered unlisted auto-hoverlink" data-info="header"
id="sec:terms-of-use">Terms of Use</h3>
<p><strong>1. License</strong></p>
<p>Broadband Forum hereby grants you the right, without charge, on a
perpetual, non-exclusive and worldwide basis, to utilize the Technical
Report for the purpose of developing, making, having made, using,
marketing, importing, offering to sell or license, and selling or
licensing, and to otherwise distribute, products complying with the
Technical Report, in all cases subject to the conditions set forth in
this notice and any relevant patent and other intellectual property
rights of third parties (which may include members of Broadband Forum).
This license grant does not include the right to sublicense, modify or
create derivative works based upon the Technical Report except to the
extent this Technical Report includes text implementable in computer
code, in which case your right under this License to create and modify
derivative works is limited to modifying and creating derivative works
of such code. For the avoidance of doubt, except as qualified by the
preceding sentence, products implementing this Technical Report are not
deemed to be derivative works of the Technical Report.</p>
<p><strong>2. NO WARRANTIES</strong></p>
<p>THIS TECHNICAL REPORT IS BEING OFFERED WITHOUT ANY WARRANTY
WHATSOEVER, AND IN PARTICULAR, ANY WARRANTY OF NONINFRINGEMENT AND ANY
IMPLIED WARRANTIES ARE EXPRESSLY DISCLAIMED. ANY USE OF THIS TECHNICAL
REPORT SHALL BE MADE ENTIRELY AT THE USER’S OR IMPLEMENTER’S OWN RISK,
AND NEITHER THE BROADBAND FORUM, NOR ANY OF ITS MEMBERS OR SUBMITTERS,
SHALL HAVE ANY LIABILITY WHATSOEVER TO ANY USER, IMPLEMENTER, OR THIRD
PARTY FOR ANY DAMAGES OF ANY NATURE WHATSOEVER, DIRECTLY OR INDIRECTLY,
ARISING FROM THE USE OF THIS TECHNICAL REPORT, INCLUDING BUT NOT LIMITED
TO, ANY CONSEQUENTIAL, SPECIAL, PUNITIVE, INCIDENTAL, AND INDIRECT
DAMAGES.</p>
<p><strong>3. THIRD PARTY RIGHTS</strong></p>
<p>Without limiting the generality of Section 2 above, BROADBAND FORUM
ASSUMES NO RESPONSIBILITY TO COMPILE, CONFIRM, UPDATE OR MAKE PUBLIC ANY
THIRD PARTY ASSERTIONS OF PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS
THAT MIGHT NOW OR IN THE FUTURE BE INFRINGED BY AN IMPLEMENTATION OF THE
TECHNICAL REPORT IN ITS CURRENT, OR IN ANY FUTURE FORM. IF ANY SUCH
RIGHTS ARE DESCRIBED ON THE TECHNICAL REPORT, BROADBAND FORUM TAKES NO
POSITION AS TO THE VALIDITY OR INVALIDITY OF SUCH ASSERTIONS, OR THAT
ALL SUCH ASSERTIONS THAT HAVE OR MAY BE MADE ARE SO LISTED.</p>
<p>All copies of this Technical Report (or any portion hereof) must
include the notices, legends, and other provisions set forth on this
page.</p>
<!-- do not edit! this file was created from PROJECT.yaml by project-parser.py -->
<div class="new-page">

</div>
<h3 class="unnumbered unlisted auto-hoverlink" data-info="header"
id="sec:issue-history">Issue History</h3>
<table class="issue-history">
<colgroup>
<col style="width: 15%" />
<col style="width: 15%" />
<col style="width: 69%" />
</colgroup>
<thead>
<tr class="header">
<th style="text-align: left;">Issue Number</th>
<th style="text-align: left;">Approval Date</th>
<th style="text-align: left;">Changes</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;"><p><a
href="https://www.broadband-forum.org/download/TR-369_Issue-1.pdf">Release
1.0</a></p></td>
<td style="text-align: left;"><p>April 2018</p></td>
<td style="text-align: left;"><p>Release contains specification for the
User Services Platform 1.0</p>
<p>Corresponds to <a
href="https://github.com/BroadbandForum/usp-data-models/releases/tag/v1.0.0">TR-181
Issue 2 Amendment 12</a></p></td>
</tr>
<tr class="even">
<td style="text-align: left;"><a
href="https://www.broadband-forum.org/download/TR-369_Corrigendum-1.pdf">Release
1.0.1</a></td>
<td style="text-align: left;">August 2018</td>
<td style="text-align: left;"><ul>
<li>Added examples and clarifications to end-to-end messaging, use of
endpoint ID, typographical fixes</li>
</ul></td>
</tr>
<tr class="odd">
<td style="text-align: left;"><a
href="https://www.broadband-forum.org/download/TR-369_Corrigendum-2.pdf">Release
1.0.2</a></td>
<td style="text-align: left;">November 2018</td>
<td style="text-align: left;"><ul>
<li>Typographical and example fixes</li>
</ul></td>
</tr>
<tr class="even">
<td style="text-align: left;"><p><a
href="https://www.broadband-forum.org/download/TR-369_Amendment-1.pdf">Release
1.1</a></p></td>
<td style="text-align: left;"><p>October 2019</p></td>
<td style="text-align: left;"><p>Release contains specification for the
User Services Platform 1.1</p>
<ul>
<li>Adds MQTT support as a Message Transfer Protocol</li>
<li>Adds a theory of operations for IoT control using USP Agents</li>
<li>Clarifications on protocol functions, error messages, and updates to
examples</li>
</ul>
<p>Corresponds to <a
href="https://github.com/BroadbandForum/usp-data-models/releases/tag/v1.1.0">TR-181
Issue 2 Amendment 13</a></p></td>
</tr>
<tr class="odd">
<td style="text-align: left;">Release 1.1.1</td>
<td style="text-align: left;">April 2020</td>
<td style="text-align: left;">Regenerated data model HTML using fixed
version of the BBF report tool</td>
</tr>
<tr class="even">
<td style="text-align: left;">Release 1.1.2</td>
<td style="text-align: left;">August 2020</td>
<td style="text-align: left;">Clarifies several examples, requirements,
and error types</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Release 1.1.3</td>
<td style="text-align: left;">November 2020</td>
<td style="text-align: left;">Corresponds to <a
href="https://github.com/BroadbandForum/data-model-template/releases/tag/v1.10.0">TR-106
Amendment 10</a> and <a
href="https://github.com/BroadbandForum/usp-data-models/releases/tag/v1.1.3">TR-181
Issue 2 Amendment 14</a></td>
</tr>
<tr class="even">
<td style="text-align: left;">Release 1.1.4</td>
<td style="text-align: left;">November 2020</td>
<td style="text-align: left;">Corresponds to <a
href="https://github.com/BroadbandForum/usp-data-models/releases/tag/v1.1.4">TR-181
Issue 2 Amendment 14 Corrigendum 1</a></td>
</tr>
<tr class="odd">
<td style="text-align: left;"><p><a
href="https://www.broadband-forum.org/download/TR-369_Amendment-2.pdf">Release
1.2</a></p></td>
<td style="text-align: left;"><p>January 2022</p></td>
<td style="text-align: left;"><p>Release contains specification for the
User Services Platform 1.2</p>
<ul>
<li>Clarify the expected responses in result of an <code>Operate</code>
message (R-OPR.4)</li>
<li>Deprecates the use of COAP as an MTP</li>
<li>GetSupportedDM
<ul>
<li>now provides the data types for parameter values</li>
<li>now allows the Agent to provide information about whether or not it
will ignore ValueChange subscriptions on a given parameter</li>
<li>now provides information about whether a command is synchronous
vs. asynchronous</li>
<li>now allows requests on specific object instances and handles
divergent data models</li>
</ul></li>
<li>Defines discovery mechanisms for Endpoints connected to STOMP and
MQTT brokers</li>
<li>Clarifies the use of search paths vs. unique key addressing in the
Add message</li>
<li>Clarifies the use of required parameters and defaults for unique
keys in the Add message</li>
<li>Annex A
<ul>
<li>now provides a theory of operations for use of the USPEventNotif
mechanism for bulk data collection using the Push! event</li>
<li>defines a new bulk data collection over MQTT mechanism</li>
</ul></li>
<li>DHCP discovery mechanism now provides a Controller Endpoint ID to
the Agent</li>
<li>Enhances ease of use and clarifies requirements for use of TLS in
USP Record integrity</li>
<li>New USP records
<ul>
<li>adds USP connect and disconnect records for use independent of
MTP</li>
<li>adds USP Record specific error mechanism and error codes</li>
<li>MQTT and STOMP no longer silently drop errors; they now report
errors in the USP Record.</li>
<li>USP Records can now include an empty payload</li>
</ul></li>
<li>Get requests
<ul>
<li>can now include a max_depth flag to limit response size</li>
<li>Get response format has been clarified to return separate elements
for sub-object</li>
</ul></li>
<li>Clarifies the requirements around processing an entire message in
the event of a failed operation when allow_partial is true vs.
false</li>
<li>Clarifies the response behavior for Get, Set, and Delete when using
a path that matches no instances</li>
<li>Fixes and enhances the use of error codes for the Operate
message</li>
<li>Clarifies and updates Controller credential/authentication theory of
operations and flow diagrams</li>
<li>Clarifies the use of subjectAltName in certificates</li>
<li>Clarifies R-E2E.4</li>
<li>Deprecated and Obsolete terms are now defined in the References and
Terminology section</li>
<li>Updated R-E3E.43</li>
<li>Deprecates R-MSG.2</li>
<li>Deprecates R-E2E.2</li>
<li>R-E2E.42 now makes TLS renegotiation forbidden</li>
<li>Modifies R-NOT.9 and adds R-NOT.10 adjusting how the Agent and
Controller should handle the subscription_id field</li>
</ul>
<p>Corresponds to <a
href="https://github.com/BroadbandForum/data-model-template/releases/tag/v1.11.0">TR-106
Amendment 11</a> and <a
href="https://github.com/BroadbandForum/usp-data-models/releases/tag/v1.2.0">TR-181
Issue 2 Amendment 15</a></p></td>
</tr>
<tr class="even">
<td style="text-align: left;"><p><a
href="https://www.broadband-forum.org/download/TR-369_Amendment-3.pdf">Release
1.3</a></p></td>
<td style="text-align: left;"><p>June 2023</p></td>
<td style="text-align: left;"><p>Release contains the specification for
the User Services Platform 1.3</p>
<ul>
<li>Adds Appendix VI, “Software Modularization and USP-Enabled
Applications Theory of Operation”</li>
<li>Adds new Unix Domain Socket MTP</li>
<li>Adds two new messages, “Register” and “Deregister”, and associated
error codes (primarily for use with Appendix VI but can be used in many
scenarios)</li>
<li>Adds new Software Module Management features</li>
<li>Adds a note about the use of the new TriggerAction parameter in
Subscription objects</li>
<li>Updates “Authentication and Authorization” to include the use of new
SecuredRole</li>
<li>Updates the Add message to allow for Search Paths and clarifies the
application of permissions during Add messages</li>
<li>Obsoletes CoAP as an MTP</li>
<li>Adds two new requirements regarding Unique Key immutability</li>
<li>Clarifies how Set should respond when using a Search Path where one
or more objects fail to update</li>
<li>Updates the use of EndpointID in WebSocket arguments and adds an
fqdn authority scheme</li>
<li>Addesses a potential attack vector with using MQTT, and updates
other MQTT behavior</li>
<li>Updates Annex A to explain use of the “Exclude” parameter</li>
<li>Updates Discovery to include the use of DHCP options for
agent-device association</li>
<li>Adds a note about USP protocol versioning and Controller/Agent
behavior</li>
<li>Clarifies and updates the use of certain error codes</li>
<li>Clarifies the behavior of Get messages when asking for specific
Multi-Instance Objects that don’t exist</li>
<li>Clarifies some behavior when responding via USP Records</li>
<li>Updates message flow diagrams to remove the implication of ordered
responses</li>
<li>Adds new requirement R-SEC.4b for Trusted Brokers</li>
</ul></td>
</tr>
<tr class="odd">
<td style="text-align: left;"><a
href="https://www.broadband-forum.org/download/TR-369_Amendment-3_Corrigendum-1.pdf">Release
1.3.1</a></td>
<td style="text-align: left;">October 2023</td>
<td style="text-align: left;">This Corrigendum has the following fixes
<ul>
<li>Fix example by populating the empty UNIX Domain Socket
references</li>
<li>Small fixes to UDS example images</li>
<li>Fix UnixDomainSocket path in example</li>
</ul></td>
</tr>
</tbody>
</table>
<h3 class="unnumbered unlisted auto-hoverlink" data-info="header"
id="sec:editors">Editors</h3>
<table class="editors">
<colgroup>
<col style="width: 20%" />
<col style="width: 17%" />
<col style="width: 25%" />
<col style="width: 36%" />
</colgroup>
<thead>
<tr class="header">
<th style="text-align: left;">Name</th>
<th style="text-align: left;">Company</th>
<th style="text-align: left;">Email</th>
<th style="text-align: left;">Role</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">Barbara Stark</td>
<td style="text-align: left;">AT&amp;T</td>
<td style="text-align: left;">barbara.stark@att.com</td>
<td style="text-align: left;">Editor/USP Project Lead</td>
</tr>
<tr class="even">
<td style="text-align: left;">Tim Spets</td>
<td style="text-align: left;">Assia</td>
<td style="text-align: left;">tspets@assia-inc.com</td>
<td style="text-align: left;">Editor/USP Project Lead</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Jason Walls</td>
<td style="text-align: left;">QA Cafe, LLC</td>
<td style="text-align: left;">jason@qacafe.com</td>
<td style="text-align: left;">Editor/Broadband User Services Work Area
Director</td>
</tr>
<tr class="even">
<td style="text-align: left;">John Blackford</td>
<td style="text-align: left;">Commscope</td>
<td style="text-align: left;">john.blackford@commscope.com</td>
<td style="text-align: left;">Editor/Broadband User Services Work Area
Director</td>
</tr>
</tbody>
</table>
<h3 class="unnumbered unlisted auto-hoverlink" data-info="header"
id="sec:acknowledgments">Acknowledgments</h3>
<table class="acknowledgments">
<colgroup>
<col style="width: 32%" />
<col style="width: 27%" />
<col style="width: 40%" />
</colgroup>
<thead>
<tr class="header">
<th style="text-align: left;">Name</th>
<th style="text-align: left;">Company</th>
<th style="text-align: left;">Email</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">Jean-Didier Ott</td>
<td style="text-align: left;">Orange</td>
<td style="text-align: left;">jeandidier.ott@orange.com</td>
</tr>
<tr class="even">
<td style="text-align: left;">Timothy Carey</td>
<td style="text-align: left;">Nokia</td>
<td style="text-align: left;">timothy.carey@nokia.com</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Steven Nicolai</td>
<td style="text-align: left;">Arris</td>
<td style="text-align: left;">Steven.Nicolai@arris.com</td>
</tr>
<tr class="even">
<td style="text-align: left;">Apostolos Papageorgiou</td>
<td style="text-align: left;">NEC</td>
<td style="text-align: left;">apostolos.Papageorgiou@neclab.eu</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Mark Tabry</td>
<td style="text-align: left;">Google</td>
<td style="text-align: left;">mtab@google.com</td>
</tr>
<tr class="even">
<td style="text-align: left;">Klaus Wich</td>
<td style="text-align: left;">Huawei</td>
<td style="text-align: left;">klaus.wich@huawei.com</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Daniel Egger</td>
<td style="text-align: left;">Axiros</td>
<td style="text-align: left;">daniel.egger@axiros.com</td>
</tr>
<tr class="even">
<td style="text-align: left;">Bahadir Danisik</td>
<td style="text-align: left;">Nokia</td>
<td style="text-align: left;">bahadir.danisik@nokia.com</td>
</tr>
<tr class="odd">
<td style="text-align: left;">William Lupton</td>
<td style="text-align: left;">Broadband Forum</td>
<td style="text-align: left;">wlupton@broadband-forum.org</td>
</tr>
<tr class="even">
<td style="text-align: left;">Matthieu Anne</td>
<td style="text-align: left;">Orange</td>
<td style="text-align: left;">matthieu.anne@orange.com</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Thales Fragoso</td>
<td style="text-align: left;">Axiros</td>
<td style="text-align: left;">thales.fragoso@axiros.com</td>
</tr>
</tbody>
</table>
<h1 class="new-page auto-hoverlink" data-info="header"
id="sec:introduction">1 Introduction</h1>
<h2 class="auto-hoverlink" data-info="header"
id="sec:executive-summary">1.1 Executive Summary</h2>
<p>This document describes the architecture, protocol, and data model
that build an intelligent User Services Platform. It is targeted towards
application developers, application service providers, vendors, consumer
electronics manufacturers, and broadband and mobile network providers
who want to expand the value of the end user’s network connection and
their connected devices.</p>
<p>The term “connected device” is a broad one, applying to the vast
array of network connected devices, consumer electronics, and computing
resources that today’s consumers are using at an increasing rate. With
the advent of “smart” platforms (phones, tablets, and wearables) plus
the emerging Internet of Things, the number of connected devices the
average user or household contains is growing by several orders of
magnitude.</p>
<p>In addition, users of the fixed and mobile broadband network are
hungry for advanced broadband and intelligent cloud services. As this
desire increases, users are turning towards over-the-top providers to
consume the security, entertainment, productivity, and storage
applications they want.</p>
<p>These realities have created an opportunity for consumer electronics
vendors, application developers, and broadband and mobile network
providers. These connected devices and services need to be managed,
monitored, troubleshot, and controlled in an easy to develop and
interoperable way. A unified framework for these is attractive if we
want to enable providers, developers, and vendors to create value for
the end user. The goal should be to create a system for developing,
deploying, and supporting these services for end users on the platform
created by their connectivity and components, that is, to be able to
treat the connected user herself as a platform for applications.</p>
<p>To address this opportunity, use cases supported by USP include:</p>
<ul>
<li>Management of IoT devices through re-usable data model objects.</li>
<li>Allowing the user to interact with their devices and services using
customer portals or control points on their own smart devices.</li>
<li>The ability to deploy and manage containerized microservices for
end-users via software modulization and USP-enabled applications.”</li>
<li>The ability to have both the application and network service
provider manage, troubleshoot, and control different aspects of the
services they are responsible for, and enabling provider
partnerships.</li>
<li>Providing a consistent user experience from mobile to home.</li>
<li>Simple migration from the CPE WAN Management Protocol <span
class="citation" data-cites="TR-069"><a href="#ref-TR-069"
role="doc-biblioref">[1]</a></span> (CWMP) – commonly known by its
document number, “TR-069” – through use of the same data model and data
modeling tools.</li>
</ul>
<h2 class="auto-hoverlink" data-info="header"
id="sec:purpose-and-scope">1.2 Purpose and Scope</h2>
<h3 class="auto-hoverlink" data-info="header" id="sec:purpose">1.2.1
Purpose</h3>
<p>This document provides the normative requirements and operational
description of the User Services Platform (USP). USP is designed for
consumer electronics/IoT, home network/gateways, smart Wi-Fi systems,
and deploying and managing other value-added services and applications.
It is targeted towards developers, application providers, and network
service providers looking to deploy those products.</p>
<h3 class="auto-hoverlink" data-info="header" id="sec:scope">1.2.2
Scope</h3>
<p>This document identifies the USP:</p>
<ul>
<li>Architecture</li>
<li>Data model interaction</li>
<li>Record structure, syntax, and rules</li>
<li>Message structure, syntax, and rules</li>
<li>Bindings that allow specific protocols to carry USP Records in their
payloads</li>
<li>Discovery and advertisement mechanisms</li>
<li>Extensions for proxying, software module management, device
modularization, firmware lifecycle management, bulk data collection,
device-agent association, and an IoT theory of operations.</li>
<li>Security credentials and logic</li>
<li>Encryption mechanisms</li>
</ul>
<p>Lastly, USP makes use of and expands the Device:2 Data Model <span
class="citation" data-cites="TR-181"><a href="#ref-TR-181"
role="doc-biblioref">[3]</a></span>. While particular Objects and
Parameters necessary to the function of USP are mentioned here, their
normative description can be found in that document.</p>
<h2 class="auto-hoverlink" data-info="header"
id="sec:references-and-terminology">1.3 References and Terminology</h2>
<h3 class="auto-hoverlink" data-info="header" id="sec:conventions">1.3.1
Conventions</h3>
<p>In this specification, several words are used to signify the
requirements of the specification. These words are always capitalized.
More information can be found in RFC 2119 <span class="citation"
data-cites="RFC2119"><a href="#ref-RFC2119"
role="doc-biblioref">[9]</a></span> for key words defined there.
Additional key words defined in the context of this specification are
DEPRECATED and OBSOLETED.</p>
<p><strong>MUST</strong></p>
<p>This word, or the term “REQUIRED”, means that the definition is an
absolute requirement of the specification.</p>
<p><strong>MUST NOT</strong></p>
<p>This phrase means that the definition is an absolute prohibition of
the specification.</p>
<p><strong>SHOULD</strong></p>
<p>This word, or the term “RECOMMENDED”, means that there could exist
valid reasons in particular circumstances to ignore this item, but the
full implications need to be understood and carefully weighed before
choosing a different course.</p>
<p><strong>SHOULD NOT</strong></p>
<p>This phrase, or the phrase “NOT RECOMMENDED” means that there could
exist valid reasons in particular circumstances when the particular
behavior is acceptable or even useful, but the full implications need to
be understood and the case carefully weighed before implementing any
behavior described with this label.</p>
<p><strong>MAY</strong></p>
<p>This word, or the term “OPTIONAL”, means that this item is one of an
allowed set of alternatives. An implementation that does not include
this option MUST be prepared to inter-operate with another
implementation that does include the option.</p>
<p><strong>DEPRECATED</strong></p>
<p>This word refers to a requirement or section of this specification
that is defined and valid in the current version of this specification
but is not strictly necessary. This may be done for various reasons,
such as irreparable problems being discovered or another more useful
method being defined to accomplish the same purpose. When this word is
applied to a requirement, it takes precedence over any normative
language in the DEPRECATED requirement. DEPRECATED requirements SHOULD
NOT be implemented. When this word is used on a section, it means the
entirety of the section SHOULD NOT be implemented – but if it is
implemented the requirements in the section are to be implemented as
written. Note that DEPRECATED requirements and sections might be removed
from the next major version of this specification.</p>
<p><strong>OBSOLETED</strong></p>
<p>This word refers to a requirement or section of this specification
that meets the definition of DEPRECATED, but which has also been
declared obsolete. Such requirements or entire sections MUST NOT be
implemented; they might be removed from a later minor version of this
specification.</p>
<h3 class="auto-hoverlink" data-info="header" id="sec:references">1.3.2
References</h3>
<p>The following references are of relevance to this Technical Report.
At the time of publication, the editions indicated were valid. All
references are subject to revision; users of this Technical Report are
therefore encouraged to investigate the possibility of applying the most
recent edition of the references listed below.</p>
<p>A list of currently valid Broadband Forum Technical Reports is
published at <a
href="https://www.broadband-forum.org">www.broadband-forum.org</a>.</p>
<div id="refs" class="references csl-bib-body" role="list">
<div id="ref-TR-069" class="csl-entry" role="listitem">
<div class="csl-left-margin">[1] </div><div
class="csl-right-inline">TR-069 Amendment 6, <em><a
href="https://www.broadband-forum.org/technical/download/TR-069.pdf">CPE
WAN Management Protocol</a></em>, Broadband Forum, 2018</div>
</div>
<div id="ref-TR-106" class="csl-entry" role="listitem">
<div class="csl-left-margin">[2] </div><div
class="csl-right-inline">TR-106, <em><a
href="https://data-model-template.broadband-forum.org">Data Model
Template for CWMP Endpoints and USP Agents</a></em>, Broadband
Forum</div>
</div>
<div id="ref-TR-181" class="csl-entry" role="listitem">
<div class="csl-left-margin">[3] </div><div
class="csl-right-inline">TR-181 Issue 2, <em><a
href="https://usp-data-models.broadband-forum.org#Device:2">Device Data
Model</a></em>, Broadband Forum</div>
</div>
<div id="ref-PROTOBUF" class="csl-entry" role="listitem">
<div class="csl-left-margin">[4] </div><div
class="csl-right-inline">Protocol Buffers v3, <em><a
href="https://developers.google.com/protocol-buffers/docs/proto3">Protocol
Buffers Mechanism for Serializing Structured Data Version 3</a></em>,
Google</div>
</div>
<div id="ref-IMEI" class="csl-entry" role="listitem">
<div class="csl-left-margin">[5] </div><div
class="csl-right-inline">IMEI Database, <em><a
href="https://imeidb.gsma.com/imei/index#">International Mobile
Equipment Identity</a></em>, GSMA</div>
</div>
<div id="ref-IANA" class="csl-entry" role="listitem">
<div class="csl-left-margin">[6] </div><div
class="csl-right-inline">IANA, <em><a
href="https://www.iana.org/">Internet Assigned Numbers
Authority</a></em>, IANA</div>
</div>
<div id="ref-IEEEREG" class="csl-entry" role="listitem">
<div class="csl-left-margin">[7] </div><div
class="csl-right-inline">Assignments, <em><a
href="https://regauth.standards.ieee.org">IEEE Registration
Authority</a></em>, IEEE</div>
</div>
<div id="ref-RFC1035" class="csl-entry" role="listitem">
<div class="csl-left-margin">[8] </div><div class="csl-right-inline">RFC
1035, <em><a href="https://tools.ietf.org/html/rfc1035">Domain Names -
Implementation and Specification</a></em>, IETF, 1987</div>
</div>
<div id="ref-RFC2119" class="csl-entry" role="listitem">
<div class="csl-left-margin">[9] </div><div class="csl-right-inline">RFC
2119, <em><a href="https://tools.ietf.org/html/rfc2119">Key words for
use in RFCs to Indicate Requirement Levels</a></em>, IETF, 1997</div>
</div>
<div id="ref-RFC2141" class="csl-entry" role="listitem">
<div class="csl-left-margin">[10] </div><div
class="csl-right-inline">RFC 2141, <em><a
href="https://tools.ietf.org/html/rfc2141">URN Syntax</a></em>, IETF,
1997</div>
</div>
<div id="ref-RFC2234" class="csl-entry" role="listitem">
<div class="csl-left-margin">[11] </div><div
class="csl-right-inline">RFC 2234, <em><a
href="https://tools.ietf.org/html/rfc2234">Augmented BNF for Syntax
Specifications: ABNF</a></em>, IETF, 1997</div>
</div>
<div id="ref-RFC3279" class="csl-entry" role="listitem">
<div class="csl-left-margin">[12] </div><div
class="csl-right-inline">RFC 3279, <em><a
href="https://datatracker.ietf.org/doc/html/rfc3279">Algorithms and
Identifiers for the Internet X.509 Public Key Infrastructure Certificate
and Certificate Revocation List (CRL) Profile</a></em>, IETF, 2002</div>
</div>
<div id="ref-RFC3315" class="csl-entry" role="listitem">
<div class="csl-left-margin">[13] </div><div
class="csl-right-inline">RFC 3315, <em><a
href="https://tools.ietf.org/html/rfc3315">Dynamic Host Configuration
Protocol for IPv6 (DHCPv6)</a></em>, IETF, 2003</div>
</div>
<div id="ref-RFC3925" class="csl-entry" role="listitem">
<div class="csl-left-margin">[14] </div><div
class="csl-right-inline">RFC 3925, <em><a
href="https://tools.ietf.org/html/rfc3925">Vendor-Identifying Vendor
Options for Dynamic Host Configuration Protocol version 4
(DHCPv4)</a></em>, IETF, 2004</div>
</div>
<div id="ref-RFC3986" class="csl-entry" role="listitem">
<div class="csl-left-margin">[15] </div><div
class="csl-right-inline">RFC 3986, <em><a
href="https://tools.ietf.org/html/rfc3986">Uniform Resource Identifier
(URI): Generic Syntax</a></em>, IETF, 2005</div>
</div>
<div id="ref-RFC5705" class="csl-entry" role="listitem">
<div class="csl-left-margin">[16] </div><div
class="csl-right-inline">RFC 5705, <em><a
href="https://tools.ietf.org/html/rfc5705">Keying Material Exporters for
Transport Layer Security (TLS)</a></em>, IETF, 2010</div>
</div>
<div id="ref-RFC6066" class="csl-entry" role="listitem">
<div class="csl-left-margin">[17] </div><div
class="csl-right-inline">RFC 6066, <em><a
href="https://tools.ietf.org/html/rfc6066">Transport Layer Security
(TLS) Extensions: Extension Definitions</a></em>, IETF, 2011</div>
</div>
<div id="ref-RFC6125" class="csl-entry" role="listitem">
<div class="csl-left-margin">[18] </div><div
class="csl-right-inline">RFC 6125, <em><a
href="https://tools.ietf.org/html/rfc6125">Representation and
Verification of Domain-Based Application Service Identity within
Internet Public Key Infrastructure Using X.509 (PKIX) Certificates in
the Context of Transport Layer Security (TLS)</a></em>, IETF, 2011</div>
</div>
<div id="ref-RFC6455" class="csl-entry" role="listitem">
<div class="csl-left-margin">[19] </div><div
class="csl-right-inline">RFC 6455, <em><a
href="https://tools.ietf.org/html/rfc6455">The WebSocket
Protocol</a></em>, IETF, 2011</div>
</div>
<div id="ref-RFC6762" class="csl-entry" role="listitem">
<div class="csl-left-margin">[20] </div><div
class="csl-right-inline">RFC 6762, <em><a
href="https://tools.ietf.org/html/rfc6762">Multicast DNS</a></em>, IETF,
2013</div>
</div>
<div id="ref-RFC6763" class="csl-entry" role="listitem">
<div class="csl-left-margin">[21] </div><div
class="csl-right-inline">RFC 6763, <em><a
href="https://tools.ietf.org/html/rfc6763">DNS-Based Service
Discovery</a></em>, IETF, 2013</div>
</div>
<div id="ref-RFC6818" class="csl-entry" role="listitem">
<div class="csl-left-margin">[22] </div><div
class="csl-right-inline">RFC 6818, <em><a
href="https://tools.ietf.org/html/rfc6818">Updates to the Internet X.509
Public Key Infrastructure Certificate and Certificate Revocation List
(CRL) Profile</a></em>, IETF, 2013</div>
</div>
<div id="ref-RFC6979" class="csl-entry" role="listitem">
<div class="csl-left-margin">[23] </div><div
class="csl-right-inline">RFC 6979, <em><a
href="https://tools.ietf.org/html/rfc6979">Deterministic Usage of the
Digital Signature Algorithm (DSA) and Elliptic Curve Digital Signature
Algorithm (ECDSA)</a></em>, IETF, 2013</div>
</div>
<div id="ref-RFC8446" class="csl-entry" role="listitem">
<div class="csl-left-margin">[24] </div><div
class="csl-right-inline">RFC 8446, <em><a
href="https://tools.ietf.org/html/rfc8446">The Transport Layer Security
(TLS) Protocol Version 1.3</a></em>, IETF, 2018</div>
</div>
<div id="ref-FIPS-180.4" class="csl-entry" role="listitem">
<div class="csl-left-margin">[25] </div><div
class="csl-right-inline">FIPS PUB 180-4, <em><a
href="https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf">Secure
Hash Standard (SHS)</a></em>, NIST</div>
</div>
<div id="ref-FIPS-186.4" class="csl-entry" role="listitem">
<div class="csl-left-margin">[26] </div><div
class="csl-right-inline">FIPS PUB 186-4, <em><a
href="https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf">Digital
Signature Standard (DSS)</a></em>, NIST</div>
</div>
<div id="ref-MQTT-3-1-1" class="csl-entry" role="listitem">
<div class="csl-left-margin">[27] </div><div
class="csl-right-inline">MQTT 3.1.1, <em><a
href="http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/mqtt-v3.1.1.html">MQ
Telemetry Transport 3.1.1</a></em>, OASIS</div>
</div>
<div id="ref-MQTT-5-0" class="csl-entry" role="listitem">
<div class="csl-left-margin">[28] </div><div
class="csl-right-inline">MQTT 5.0, <em><a
href="https://docs.oasis-open.org/mqtt/mqtt/v5.0/mqtt-v5.0.html">MQ
Telemetry Transport 5.0</a></em>, OASIS</div>
</div>
<div id="ref-SOAP-1-1" class="csl-entry" role="listitem">
<div class="csl-left-margin">[29] </div><div
class="csl-right-inline">SOAP 1.1, <em><a
href="https://www.w3.org/TR/2000/NOTE-SOAP-20000508/">Simple Object
Access Protocol (SOAP) 1.1</a></em>, W3C, 2000</div>
</div>
<div id="ref-XMLSCHEMA-2" class="csl-entry" role="listitem">
<div class="csl-left-margin">[30] </div><div
class="csl-right-inline">XML Schema Part 2, <em><a
href="https://www.w3.org/TR/xmlschema-2/">XML Schema Part 2: Datatypes
Second Edition</a></em>, W3C, 2004</div>
</div>
<div id="ref-RFC4122" class="csl-entry" role="listitem">
<div class="csl-left-margin">[31] </div><div
class="csl-right-inline">RFC 4122, <em><a
href="https://tools.ietf.org/html/rfc4122">A Universally Unique
IDentifier (UUID) URN Namespace</a></em>, 2005</div>
</div>
<div id="ref-RFC4180" class="csl-entry" role="listitem">
<div class="csl-left-margin">[32] </div><div
class="csl-right-inline">RFC 4180, <em><a
href="https://tools.ietf.org/html/rfc4180">Common Format and MIME Type
for Comma-Separated Values (CSV) Files</a></em>, 2005</div>
</div>
<div id="ref-RFC5246" class="csl-entry" role="listitem">
<div class="csl-left-margin">[33] </div><div
class="csl-right-inline">RFC 5246, <em><a
href="https://tools.ietf.org/html/rfc5246">The Transport Layer Security
(TLS) Protocol Version 1.2</a></em>, 2008</div>
</div>
<div id="ref-RFC5280" class="csl-entry" role="listitem">
<div class="csl-left-margin">[34] </div><div
class="csl-right-inline">RFC 5280, <em><a
href="https://tools.ietf.org/html/rfc5280">Internet X.509 Public Key
Infrastructure Certificate and Certificate Revocation List (CRL)
Profile</a></em>, 2008</div>
</div>
<div id="ref-RFC7159" class="csl-entry" role="listitem">
<div class="csl-left-margin">[35] </div><div
class="csl-right-inline">RFC 7159, <em><a
href="https://tools.ietf.org/html/rfc7159">The JavaScript Object
Notation (JSON) Data Interchange Format</a></em>, 2014</div>
</div>
<div id="ref-RFC7252" class="csl-entry" role="listitem">
<div class="csl-left-margin">[36] </div><div
class="csl-right-inline">RFC 7252, <em><a
href="https://tools.ietf.org/html/rfc7252">The Constrained Application
Protocol (CoAP)</a></em>, 2014</div>
</div>
<div id="ref-RFC7925" class="csl-entry" role="listitem">
<div class="csl-left-margin">[37] </div><div
class="csl-right-inline">RFC 7925, <em><a
href="https://tools.ietf.org/html/rfc7925">Transport Layer Security
(TLS) / Datagram Transport Layer Security (DTLS) Profiles for the
Internet of Things</a></em>, 2016</div>
</div>
<div id="ref-RFC7959" class="csl-entry" role="listitem">
<div class="csl-left-margin">[38] </div><div
class="csl-right-inline">RFC 7959, <em><a
href="https://tools.ietf.org/html/rfc7959">Block-Wise Transfers in the
Constrained Application Protocol (CoAP)</a></em>, 2016</div>
</div>
<div id="ref-RFC8766" class="csl-entry" role="listitem">
<div class="csl-left-margin">[39] </div><div
class="csl-right-inline">RFC 8766, <em><a
href="https://tools.ietf.org/html/rfc8766">Discovery Proxy for Multicast
DNS-Based Service Discovery</a></em>, 2020</div>
</div>
<div id="ref-STOMP-1-2" class="csl-entry" role="listitem">
<div class="csl-left-margin">[40] </div><div
class="csl-right-inline">STOMP-1-2, <em><a
href="https://stomp.github.io/stomp-specification-1.2.html">Simple Text
Oriented Message Protocol</a></em></div>
</div>
</div>
<h2 class="auto-hoverlink" data-info="header" id="sec:definitions">1.4
Definitions</h2>
<p>The following terminology is used throughout this specification.</p>
<p><strong>Agent</strong></p>
<p>An Agent is an Endpoint that exposes Service Elements to one or more
Controllers.</p>
<p><strong>Binding</strong></p>
<p>A Binding is a means of sending Messages across an underlying Message
Transfer Protocol.</p>
<p><strong>Command</strong></p>
<p>The term used to define and refer to an Object-specific Operation in
the Agent’s Instantiated or Supported Data Model.</p>
<p><strong>Connection Capabilities</strong></p>
<p>Connection Capabilities are information related to an Endpoint that
describe how to communicate with that Endpoint, and provide a very basic
idea of what sort of function the Endpoint serves.</p>
<p><strong>Controller</strong></p>
<p>A Controller is an Endpoint that manipulates Service Elements through
one or more Agents.</p>
<p><strong>Discovery</strong></p>
<p>Discovery is the process by which Controllers become aware of Agents
and Agents become aware of Controllers.</p>
<p><strong>Endpoint</strong></p>
<p>An Endpoint is a termination point for a Message.</p>
<p><strong>Endpoint Identifier</strong></p>
<p>The Endpoint Identifier is a globally unique USP layer identifier of
an Endpoint.</p>
<p><strong>End to End Message Exchange</strong></p>
<p>USP feature that allows for message integrity protection through the
creation of a session context.</p>
<p><strong>Error</strong></p>
<p>An Error is a Message that contains failure information associated
with a Request.</p>
<p><strong>Event</strong></p>
<p>An Event is a set of conditions that, when met, triggers the sending
of a Notification.</p>
<p><strong>Expression</strong></p>
<p>See also Search Expression.</p>
<p><strong>Expression Component</strong></p>
<p>An Expression Component is the part of a Search Expression that gives
the matching Parameter criteria for the search. It is comprised of an
Expression Parameter followed by an Expression Operator followed by an
Expression Constant.</p>
<p><strong>Expression Constant</strong></p>
<p>The Expression Constant is the value used to compare against the
Expression Component to determine if a search matches a given
Object.</p>
<p><strong>Expression Operator</strong></p>
<p>The Expression Operator is the operator used to determine how the
Expression Component will be evaluated against the Expression Constant,
i.e., equals (==), not equals (!=), contains (~=), less than (&lt;),
greater than (&gt;), less than or equal (&lt;=) and greater than or
equal (&gt;=).</p>
<p><strong>Expression Parameter</strong></p>
<p>The Expression Parameter is a Parameter relative to the Path Name
where an Expression Variable occurs that will be used with the
Expression Constant to evaluate the Expression Component.</p>
<p><strong>Expression Variable</strong></p>
<p>The Expression Variable is an identifier used to allow relative
addressing when building an Expression Component.</p>
<p><strong>Instantiated Data Model</strong></p>
<p>The Instantiated Data Model of an Agent represents the current set of
Service Elements (and their state) that are exposed to one or more
Controllers.</p>
<p><strong>Instance Identifier</strong></p>
<p>A term used to identify an Instance of a Multi-Instance Object (also
called a Row of a Table). While all Multi-Instance Objects have an
Instance Number that can be used as an Instance Identifier, an Object
Instance can also be referenced using any of that Object’s Unique
Keys.</p>
<p><strong>Instance Number</strong></p>
<p>An Instance Number is a numeric Instance Identifier assigned by the
Agent to instances of Multi-Instance Objects in an Agent’s Instantiated
Data Model.</p>
<p><strong>Message</strong></p>
<p>A Message refers to the contents of a USP layer communication
including exactly one Message Header and exactly one Message Body.</p>
<p><strong>Message Body</strong></p>
<p>The Message Body is the portion of a Message that contains one of the
following: Request, Response, or Error.</p>
<p><strong>Message Header</strong></p>
<p>The portion of a Message that contains elements that provide
information about the Message, including the Message type, and Message
ID elements.</p>
<p><strong>Message ID</strong></p>
<p>A Message ID is an identifier used to associate a Response or Error
with a Request.</p>
<p><strong>Message Transfer Protocol</strong></p>
<p>A Message Transfer Protocol (MTP) is the protocol at a layer below
USP that carries a Message, e.g., WebSocket.</p>
<p><strong>Multi-Instance Object</strong></p>
<p>A Multi-Instance Object refers to an Object that can be created or
deleted in the Agent’s Instantiated Data Model. Also called a Table.</p>
<p><strong>Notification</strong></p>
<p>A Notification is a Request from an Agent that conveys information
about an Event to a Controller that has a Subscription to that
event.</p>
<p><strong>Object</strong></p>
<p>An Object refers to a defined type that an Agent represents and
exposes. A Service Element may be comprised of one or more Objects and
Sub-Objects.</p>
<p><strong>Object Instance</strong></p>
<p>An Object Instance refers to a single instance Object of a type
defined by a Multi-Instance Object in the Agent’s Instantiated Data
Model. Also called a Row of a Table.</p>
<p><strong>Object Instance Path</strong></p>
<p>An Object Instance Path is a Path Name that addresses an Instance of
a Multi-Instance Object (also called a Row of a Table). It includes the
Object Path followed by an Instance Identifier. See <a
href="#sec:path-names" class="heading">Path Names</a>.</p>
<p><strong>Object Path</strong></p>
<p>An Object Path is a Path Name that addresses an Object. In the case
of Multi-Instance Objects, an Object Path addresses the Object type
itself rather than instances of that Object, which are addressed by
Object Instance Paths. See <a href="#sec:path-names"
class="heading">Path Names</a>.</p>
<p><strong>Operation</strong></p>
<p>A method defined for a particular Service Element that can be invoked
with the Operate Message.</p>
<p><strong>Parameter</strong></p>
<p>A Parameter is a variable or attribute of an Object. Parameters have
both type and value.</p>
<p><strong>Parameter Path</strong></p>
<p>A Parameter Path is a Path Name that addresses a Parameter of an
Object or Object Instance. See <a href="#sec:path-names"
class="heading">Path Names</a>.</p>
<p><strong>Path Name</strong></p>
<p>A Path Name is a fully qualified reference to an Object, Object
Instance, or Parameter in an Agent’s Instantiated or Supported Data
Model. See <a href="#sec:path-names" class="heading">Path Names</a>.</p>
<p><strong>Path Reference</strong></p>
<p>A Path Reference is a Parameter data type that contains a Path Name
to an Object or Parameter that may be automatically followed by using
certain Path Name syntax.</p>
<p><strong>Record</strong></p>
<p>The Record is defined as the Message Transfer Protocol (MTP) payload,
encapsulating a sequence of datagrams that comprise of the Message as
well as essential protocol information such as the USP version, the
source Endpoint ID, and the target Endpoint ID. It can also contain
additional metadata needed for providing integrity protection, payload
protection and delivery of fragmented Messages.</p>
<p><strong>Register</strong></p>
<p>To Register means to use the Register message to inform a Controller
of Service Elements that this Agent represents.</p>
<p><strong>Registered</strong></p>
<p>Registered Service Elements are those elements represented by an
Agent that have been the subject of a Register message.</p>
<p><strong>Relative Path</strong></p>
<p>A Relative Path is the remaining Path Name information necessary to
form a Path Name given a parent Object Path. It is used for message
efficiency when addressing Path Names.</p>
<p><strong>Request</strong></p>
<p>A Request is a type of Message that either requests the Agent perform
some action (create, update, delete, operate, etc.), requests
information about an Agent or one or more Service Elements, or acts as a
means to deliver Notifications and Register Messages from the Agent to
the Controller. A Request usually requires a Response.</p>
<p><strong>Response</strong></p>
<p>A Response is a type of Message that provides return information
about the successful processing of a Request.</p>
<p><strong>Role</strong></p>
<p>A Role refers to the set of permissions (i.e., an access control
list) that a Controller is granted by an Agent to interact with objects
in its Instantiated Data Model.</p>
<p><strong>Row</strong></p>
<p>The term Row refers to an Instance of a Multi-Instance Object in the
Agent’s Instantiated Data Model.</p>
<p><strong>Search Expression</strong></p>
<p>A Search Expression is used in a Search Path to apply specified
search criteria to address a set of Multi-Instance Objects and/or their
Parameters.</p>
<p><strong>Search Path</strong></p>
<p>A Search Path is a Path Name that contains search criteria for
addressing a set of Multi-Instance Objects and/or their Parameters. A
Search Path may contain a Search Expression or Wildcard.</p>
<p><strong>Service Element</strong></p>
<p>A Service Element represents a piece of service functionality that is
exposed by an Agent, usually represented by one or more Objects.</p>
<p><strong>Source Endpoint</strong></p>
<p>The Endpoint that was the sender of a message.</p>
<p><strong>Subscription</strong></p>
<p>A Subscription is a set of logic that tells an Agent which
Notifications to send to a particular Controller.</p>
<p><strong>Supported Data Model</strong></p>
<p>The Supported Data Model of an Agent represents the complete set of
Service Elements it is capable of exposing to a Controller. It is
defined by the union of all of the Device Type Definitions the Agent
exposes to the Controller.</p>
<p><strong>Table</strong></p>
<p>The term Table refers to a Multi-Instance Object in an Agent’s
Instantiated or Supported Data Model.</p>
<p><strong>Target Endpoint</strong></p>
<p>The Endpoint that was the intended receiver of a message.</p>
<p><strong>Trusted Broker</strong></p>
<p>An intermediary that either (1) ensures the Endpoint ID in all
brokered Endpoint’s USP Record <code>from_id</code> matches the Endpoint
ID of those Endpoint’s certificates or credentials, before sending on a
USP Record to another Endpoint, or (2) is part of a closed ecosystem
that “knows” (certain) Endpoints can be trusted not to spoof the
Endpoint ID.</p>
<p><strong>Unique Key</strong></p>
<p>A Unique Key of a Multi-Instance Object is a set of one or more
Parameters that uniquely identify the instance of an Object in the
Agent’s Instantiated Data Model and can therefore be used as an Instance
Identifier.</p>
<p><strong>Unique Key Parameter</strong></p>
<p>A Parameter that is a member of any of a Multi-Instance Object’s
Unique Keys.</p>
<p><strong>User Services Platform</strong></p>
<p>The User Services Platform consists of a data model, architecture,
and communications protocol to transform consumer broadband networks
into a platform for the development, deployment, and support of
broadband enabled applications and services.</p>
<p><strong>USP Domain</strong></p>
<p>The USP Domain is a set of all Controllers and Agents that are likely
to communicate with each other in a given network or internetwork with
the goal of supporting a specific application or set of
applications.</p>
<p><strong>USP Relationship</strong></p>
<p>A Controller and Agent are considered to have a USP Relationship when
they are capable of sending and accepting messages to/from each other.
This usually means the Controller is added to the Agent’s Controller
table in its Instantiated Data Model.</p>
<p><strong>Wildcard</strong></p>
<p>A Wildcard is used in a Search Path to address all Object Instances
of a Multi-Instance Object.</p>
<h2 class="auto-hoverlink" data-info="header" id="sec:abbreviations">1.5
Abbreviations</h2>
<p>This specification uses the following abbreviations:</p>
<table>
<thead>
<tr class="header">
<th style="text-align: left;">abbreviation</th>
<th style="text-align: left;">term</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">ABNF</td>
<td style="text-align: left;">Augmented Backus-Naur Form</td>
</tr>
<tr class="even">
<td style="text-align: left;">CID</td>
<td style="text-align: left;">Company Identifier</td>
</tr>
<tr class="odd">
<td style="text-align: left;">CSV</td>
<td style="text-align: left;">Comma-Separated Values</td>
</tr>
<tr class="even">
<td style="text-align: left;">CWMP</td>
<td style="text-align: left;">CPE WAN Management Protocol</td>
</tr>
<tr class="odd">
<td style="text-align: left;">DNS</td>
<td style="text-align: left;">Domain Name Service</td>
</tr>
<tr class="even">
<td style="text-align: left;">DNS-SD</td>
<td style="text-align: left;">Domain Name Service - Service
Discovery</td>
</tr>
<tr class="odd">
<td style="text-align: left;">DU</td>
<td style="text-align: left;">Deployment Unit</td>
</tr>
<tr class="even">
<td style="text-align: left;">E2E</td>
<td style="text-align: left;">End to End (Message Exchange)</td>
</tr>
<tr class="odd">
<td style="text-align: left;">EE</td>
<td style="text-align: left;">Execution Environment</td>
</tr>
<tr class="even">
<td style="text-align: left;">EU</td>
<td style="text-align: left;">Execution Unit</td>
</tr>
<tr class="odd">
<td style="text-align: left;">FIFO</td>
<td style="text-align: left;">First-In-First-Out</td>
</tr>
<tr class="even">
<td style="text-align: left;">FQDN</td>
<td style="text-align: left;">Fully-Qualified Domain Name</td>
</tr>
<tr class="odd">
<td style="text-align: left;">GSDM</td>
<td style="text-align: left;">Get Supported Data Model (informal of
GetSupportedDM message)</td>
</tr>
<tr class="even">
<td style="text-align: left;">HMAC</td>
<td style="text-align: left;">Hash Message Authentication Code</td>
</tr>
<tr class="odd">
<td style="text-align: left;">HTTP</td>
<td style="text-align: left;">Hypertext Transport Protocol</td>
</tr>
<tr class="even">
<td style="text-align: left;">IPv4/v6</td>
<td style="text-align: left;">Internet Protocol (version 4 or version
6)</td>
</tr>
<tr class="odd">
<td style="text-align: left;">JSON</td>
<td style="text-align: left;">Java Script Object Notation</td>
</tr>
<tr class="even">
<td style="text-align: left;">LAN</td>
<td style="text-align: left;">Local Area Network</td>
</tr>
<tr class="odd">
<td style="text-align: left;">MAC</td>
<td style="text-align: left;">Message Authentication Code</td>
</tr>
<tr class="even">
<td style="text-align: left;">mDNS</td>
<td style="text-align: left;">Multicast Domain Name Service</td>
</tr>
<tr class="odd">
<td style="text-align: left;">MTP</td>
<td style="text-align: left;">Message Transfer Protocol</td>
</tr>
<tr class="even">
<td style="text-align: left;">MQTT</td>
<td style="text-align: left;">Message Queue Telemetry Transport</td>
</tr>
<tr class="odd">
<td style="text-align: left;">OUI</td>
<td style="text-align: left;">Organizationally Unique Identifier</td>
</tr>
<tr class="even">
<td style="text-align: left;">PEN</td>
<td style="text-align: left;">Private Enterprise Number</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Protobuf</td>
<td style="text-align: left;">Protocol Buffers</td>
</tr>
<tr class="even">
<td style="text-align: left;">PSS</td>
<td style="text-align: left;">Probabilistic Signature Scheme</td>
</tr>
<tr class="odd">
<td style="text-align: left;">SAR</td>
<td style="text-align: left;">Segmentation And Reassembly</td>
</tr>
<tr class="even">
<td style="text-align: left;">SMM</td>
<td style="text-align: left;">Software Module Management</td>
</tr>
<tr class="odd">
<td style="text-align: left;">SOAP</td>
<td style="text-align: left;">Simple Object Access Protocol</td>
</tr>
<tr class="even">
<td style="text-align: left;">SSID</td>
<td style="text-align: left;">Service Set Identifier</td>
</tr>
<tr class="odd">
<td style="text-align: left;">STOMP</td>
<td style="text-align: left;">Simple Text-Oriented Messaging
Protocol</td>
</tr>
<tr class="even">
<td style="text-align: left;">TLS</td>
<td style="text-align: left;">Tranport Layer Security</td>
</tr>
<tr class="odd">
<td style="text-align: left;">TLV</td>
<td style="text-align: left;">Type-Length-Value</td>
</tr>
<tr class="even">
<td style="text-align: left;">TOFU</td>
<td style="text-align: left;">Trust on First Use</td>
</tr>
<tr class="odd">
<td style="text-align: left;">TR</td>
<td style="text-align: left;">Technical Report</td>
</tr>
<tr class="even">
<td style="text-align: left;">UDS</td>
<td style="text-align: left;">UNIX Domain Socket</td>
</tr>
<tr class="odd">
<td style="text-align: left;">URI</td>
<td style="text-align: left;">Uniform Resource Identifier</td>
</tr>
<tr class="even">
<td style="text-align: left;">URL</td>
<td style="text-align: left;">Uniform Resource Locator</td>
</tr>
<tr class="odd">
<td style="text-align: left;">USP</td>
<td style="text-align: left;">User Services Platform</td>
</tr>
<tr class="even">
<td style="text-align: left;">UUID</td>
<td style="text-align: left;">Universally Unique Identifier</td>
</tr>
<tr class="odd">
<td style="text-align: left;">WAN</td>
<td style="text-align: left;">Wide Area Network</td>
</tr>
<tr class="even">
<td style="text-align: left;">XML</td>
<td style="text-align: left;">eXtensible Markup Language</td>
</tr>
</tbody>
</table>
<h2 class="auto-hoverlink" data-info="header"
id="sec:specification-impact">1.6 Specification Impact</h2>
<h3 class="auto-hoverlink" data-info="header"
id="sec:energy-efficiency">1.6.1 Energy efficiency</h3>
<p>The User Services Platform reaches into more and newer connected
devices, and expands on the management of physical hardware, including
power management. In addition, USP directly enables smart home, smart
building, and other smart energy applications.</p>
<h3 class="auto-hoverlink" data-info="header" id="sec:security">1.6.2
Security</h3>
<p>Any solution that provides a mechanism to manage, monitor, diagnose,
and control a connected user’s network, devices, and applications must
prioritize security to protect user data and prevent malicious use of
the system. This is especially important with certain high-risk smart
applications like medicine or emergency services.</p>
<p>However reliable the security of communications protocols, in a
platform that enables interoperable components that may or may not be
connected with protocols outside the scope of the specification,
security must be considered from end-to-end. To realize this, USP
contains its own security mechanisms.</p>
<h3 class="auto-hoverlink" data-info="header" id="sec:privacy">1.6.3
Privacy</h3>
<p><strong>Privacy</strong> is the right of an individual or group to
control or influence what information related to them may be collected,
processed, and stored and by whom, and to whom that information may be
disclosed.</p>
<p><strong>Assurance of privacy</strong> depends on whether stakeholders
expect, or are legally required, to have information protected or
controlled from certain uses. As with security, the ability for users to
control who has access to their data is of primary importance in the
world of the connected user, made clear by users as well as
regulators.</p>
<p>USP contains rigorous access control and authorization mechanisms to
ensure that data is only used by those that have been enabled by the
user.</p>
<h1 class="auto-hoverlink" data-info="header" id="sec:architecture">2
Architecture</h1>
<p>The User Services Platform consists of a collection of Endpoints
(Agents and Controllers) that allow applications to manipulate Service
Elements. These Service Elements are made up of a set of Objects and
Parameters that model a given service, such as network interfaces,
software modules, device firmware, remote elements proxied through
another interface, virtual elements, or other managed services.</p>
<p>USP is made up of several architectural components:</p>
<ul>
<li>Mechanisms for discovery and trust establishment</li>
<li>A method for encoding messages for transport</li>
<li>A system for end-to-end confidentiality, integrity and identity
authentication</li>
<li>Transport of messages over one or more Message Transfer Protocols
(MTPs) with associated MTP security</li>
<li>A set of standardized messages based on the CRUD model (create,
read, update, delete), plus an Object defined operations mechanism and a
notification mechanism (CRUD-ON)</li>
<li>Authorization and access control on a per element basis</li>
<li>A method for modeling service elements using a set of Objects,
Parameters, operations, and events (supported and instantiated data
models)</li>
</ul>
<h2 class="auto-hoverlink" data-info="header" id="sec:endpoints">2.1
Endpoints</h2>
<p>A USP Endpoint can act as Agent or a Controller. Controllers only
send messages to Agents, and Agents send messages to Controllers. A USP
Endpoint communicates with other Endpoints over one or more Message
Transfer Protocols (MTP). This communication is secured by the MTP, or
by the use of a <a
href="#sec:exchange-of-usp-records-within-an-e2e-session-context"
class="heading">USP Session Context</a>, or both.</p>
<figure id="fig:usp-agent-and-controller-architecture">
<img src="architecture/usp_architecture.png"
id="img:usp-agent-and-controller-architecture"
alt="USP Agent and Controller Architecture" />
<figcaption><div class="auto-hoverlink"
data-anchor="fig:usp-agent-and-controller-architecture">
Figure 1: USP Agent and Controller Architecture
</div></figcaption>
</figure>
<h3 class="auto-hoverlink" data-info="header" id="sec:agents">2.1.1
Agents</h3>
<p>A USP Agent exposes (to Controllers) one or more Service Elements
that are represented in its data model. It contains or references both
an Instantiated Data Model (representing the current state of Service
Elements it represents) and a Supported Data Model.</p>
<h3 class="auto-hoverlink" data-info="header" id="sec:controllers">2.1.2
Controllers</h3>
<p>A USP Controller manipulates (through Agents) a set of Service
Elements that are represented in Agent data models. It may maintain a
database of Agents, their capabilities, and their states, in any
combination. A Controller usually acts as an interface to a user
application or policy engine that uses the User Services Platform to
address particular use cases.</p>
<h2 class="auto-hoverlink" data-info="header"
id="sec:endpoint-identifier">2.2 Endpoint Identifier</h2>
<p>Endpoints are identified by an Endpoint Identifier.</p>
<p>The Endpoint Identifier is a locally or globally unique USP layer
identifier of an Endpoint. Whether it is globally or locally unique
depends on the scheme used for assignment.</p>
<p>The Endpoint Identifier (ID) is used in the USP Record and various
Parameters in a USP Message to uniquely identify Controller and Agent
Endpoints. It can be globally or locally unique, either among all
Endpoints or among all Controllers or all Agents, depending on the
scheme used for assignment.</p>
<p>The Endpoint ID is comprised of two mandatory and one optionally
mandatory components: <code>authority-scheme</code>,
<code>authority-id</code>, and <code>instance-id</code>.</p>
<p>These three components are combined as:</p>
<p><code>authority-scheme ":" [authority-id] ":" instance-id</code></p>
<p>The format of the authority-id is dictated by the authority-scheme.
The format of the instance-id is dictated either by the authority-scheme
or by the entity identified by the authority-id.</p>
<p>When used in a certificate, an Endpoint ID is expressed as a urn in
the bbf namespace as:</p>
<p><code>"urn:bbf:usp:id:" authority-scheme ":" [authority-id] ":" instance-id</code></p>
<p>When used anywhere else (e.g. in the <code>to_id</code> and
<code>from_id</code> of a USP Record), the namespace information is
omitted, and the Endpoint ID is expressed as:</p>
<p><code>authority-scheme ":" [authority-id] ":" instance-id</code></p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:use-of-authority-scheme-and-authority-id">2.2.1 Use of
authority-scheme and authority-id</h3>
<p>The authority-scheme follows the following syntax:</p>
<p><code>authority-scheme = "oui" | "cid" | "pen" | "self"  | "user" | "os" | "ops" | "uuid" | "imei" | "proto" | "doc" | "fqdn"</code></p>
<p>How these authority-scheme values impact the format and values of
authority-id and instance-id is described below.</p>
<p>The authority defined by an OUI, CID, Private Enterprise Number
(including OUI used in “ops” and “os” authority scheme), or fully
qualified domain name is responsible for ensuring the uniqueness of the
resulting Endpoint ID. Uniqueness can be global, local, unique across
all Endpoints, or unique among all Controllers or all Agents. For the
“user” authority scheme, the assigning user or machine is responsible
for ensuring uniqueness. For the “self” authority scheme, the Endpoint
is responsible for ensuring uniqueness.</p>
<p><strong><span id="r-arc.0"
class="auto-hoverlink">R-ARC.0</span></strong> - A Controller and Agent
within the same USP Domain MAY use the same Endpoint ID.</p>
<p><strong><span id="r-arc.1"
class="auto-hoverlink">R-ARC.1</span></strong> - Endpoints MUST tolerate
the same Endpoint ID being used by an Agent and a Controller in the same
USP Domain.</p>
<p><strong><span id="r-arc.2"
class="auto-hoverlink">R-ARC.2</span></strong> - Endpoints that share
the same Endpoint ID MUST NOT communicate with each other via USP.</p>
<p>No conflict identification or resolution process is defined in USP to
deal with a situation where an Endpoint ID is not unique among either
all Agents or all Controllers in whatever USP Domain it operates.
Therefore, a non-unique Endpoint ID will result in unpredictable
behavior. An Endpoint ID that changes after having been used to identify
an Endpoint can also result in unpredictable behavior.</p>
<p>Unless the authority responsible for assigning an Endpoint ID assigns
meaning to an Agent and Controller having the same Endpoint ID, no
meaning can be construed. That is, unless the assigning authority
specifically states that an Agent and Controller with the same Endpoint
ID are somehow related, no relationship can be assumed to exist.</p>
<p><strong><span id="r-arc.2a"
class="auto-hoverlink">R-ARC.2a</span></strong> - Endpoints MUST follow
the authority-scheme requirements outlined in the following table:</p>
<table>
<colgroup>
<col style="width: 25%" />
<col style="width: 75%" />
</colgroup>
<thead>
<tr class="header">
<th style="text-align: right;">authority-scheme</th>
<th style="text-align: left;">usage and rules for authority-id and
instance-id</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: right;"><code>oui</code></td>
<td style="text-align: left;"><code>authority-id</code> MUST be an OUI
(now called “MAC Address Block Large” or “MA-L”) assigned and registered
by the IEEE Registration Authority <span class="citation"
data-cites="IEEEREG"><a href="#ref-IEEEREG"
role="doc-biblioref">[7]</a></span> to the entity responsible for this
Endpoint. authority-id MUST use hex encoding of the 24-bit ID (resulting
in 6 hex characters). <code>instance-id</code> syntax is defined by this
entity, who is also responsible for determining instance-id assignment
mechanisms and for ensuring uniqueness of the instance-id within the
context of the OUI.
Example:<code>oui:00256D:my-unique-bbf-id-42</code></td>
</tr>
<tr class="even">
<td style="text-align: right;"><code>cid</code></td>
<td style="text-align: left;"><code>authority-id</code> MUST be a CID
assigned and registered by the IEEE Registration Authority <span
class="citation" data-cites="IEEEREG"><a href="#ref-IEEEREG"
role="doc-biblioref">[7]</a></span> to the entity responsible for this
Endpoint. <code>authority-id</code> MUST use hex encoding of the 24-bit
ID (resulting in 6 hex characters).<br />
<code>instance-id</code> syntax is defined by this entity, who is also
responsible for determining instance-id assignment mechanisms and for
ensuring uniqueness of the instance-id within the context of the
CID.<br />
Example: cid:3AA3F8:my-unique-usp-id-42</td>
</tr>
<tr class="odd">
<td style="text-align: right;"><code>pen</code></td>
<td style="text-align: left;"><code>authority-id</code> MUST be a
Private Enterprise Number assigned and registered by IANA <span
class="citation" data-cites="IANA"><a href="#ref-IANA"
role="doc-biblioref">[6]</a></span> to the entity responsible for this
Endpoint. <code>authority-id</code> MUST use decimal encoding of the
IANA-assigned number.<br />
<code>instance-id</code> syntax is defined by this entity, who is also
responsible for determining instance-id assignment mechanisms and for
ensuring uniqueness of the instance-id within the context of the Private
Enterprise Number.<br />
Example: <code>pen:3561:my-unique-bbf-id-42</code></td>
</tr>
<tr class="even">
<td style="text-align: right;"><code>self</code></td>
<td style="text-align: left;">When present, an <code>authority-id</code>
for “<code>self</code>” MUST be between 1 and 6 non-reserved characters
in length. When present, it is generated by the Endpoint. It is not
required to have an <code>authority-id</code> for
“<code>self</code>”.<br />
The Endpoint ID, including <code>instance-id</code>, is generated by the
Endpoint.<br />
The Endpoint MUST change its Endpoint ID if it ever encounters another
Endpoint using the identical Endpoint ID.<br />
Example: <code>self::my-Agent</code></td>
</tr>
<tr class="odd">
<td style="text-align: right;"><code>user</code></td>
<td style="text-align: left;">An <code>authority-id</code> for
“<code>user</code>” MUST be between 0 and 6 non-reserved characters in
length.<br />
The Endpoint ID, including <code>instance-id</code>, is assigned to the
Endpoint via a user or management interface.</td>
</tr>
<tr class="even">
<td style="text-align: right;"><code>os</code></td>
<td style="text-align: left;"><code>authority-id</code> MUST be
zero-length.<br />
<code>instance-id</code>is
<code>&lt;OUI&gt; "-" &lt;SerialNumber&gt;</code>, as defined in TR-069
<span class="citation" data-cites="TR-069"><a href="#ref-TR-069"
role="doc-biblioref">[1]</a></span> Section 3.4.4.<br />
Example: <code>os::00256D-0123456789</code></td>
</tr>
<tr class="odd">
<td style="text-align: right;"><code>ops</code></td>
<td style="text-align: left;"><code>authority-id</code> MUST be
zero-length.<br />
<code>instance-id</code> is
<code>&lt;OUI&gt; "-" &lt;ProductClass&gt; "-" &lt;SerialNumber&gt;</code>,
as defined in TR-069 <span class="citation" data-cites="TR-069"><a
href="#ref-TR-069" role="doc-biblioref">[1]</a></span> Section
3.4.4.<br />
Example: <code>ops::00256D-STB-0123456789</code></td>
</tr>
<tr class="even">
<td style="text-align: right;"><code>uuid</code></td>
<td style="text-align: left;"><code>authority-id</code> MUST be
zero-length.<br />
<code>instance-id</code> is a UUID <span class="citation"
data-cites="RFC4122"><a href="#ref-RFC4122"
role="doc-biblioref">[31]</a></span><br />
Example:<code>uuid::f81d4fae-7dec-11d0-a765-00a0c91e6bf6</code></td>
</tr>
<tr class="odd">
<td style="text-align: right;"><code>imei</code></td>
<td style="text-align: left;"><code>authority-id</code> MUST be
zero-length.<br />
<code>instance-id</code> is an IMEI <span class="citation"
data-cites="IMEI"><a href="#ref-IMEI"
role="doc-biblioref">[5]</a></span> as defined by GSMA.<br />
Example: <code>imei::990000862471854</code></td>
</tr>
<tr class="even">
<td style="text-align: right;"><code>proto</code></td>
<td style="text-align: left;"><code>authority-id</code> MUST be between
0 and 6 non-reserved characters (except “.”) in length.<br />
“<code>proto</code>” is used for prototyping purposes only. Any
<code>authority-id</code> and <code>instance-id</code> value (or scheme
for creating the value) is left to the prototyper.<br />
Example: <code>proto::my-Agent</code></td>
</tr>
<tr class="odd">
<td style="text-align: right;"><code>doc</code></td>
<td style="text-align: left;"><code>authority-id</code> MUST be between
0 and 6 non-reserved characters in length.<br />
“<code>doc</code>” is used for documentation purposes only (for creating
examples in slide decks, tutorials, and other explanatory documents).
Any <code>authority-id</code> and <code>instance-id</code> value (or
scheme for creating the value) is left to the document creator.</td>
</tr>
<tr class="even">
<td style="text-align: right;"><code>fqdn</code></td>
<td style="text-align: left;"><code>authority-id</code> MUST be
zero-length.<br />
<code>instance-id</code> is a valid fully qualified domain name,
wildcards are not permitted.<br />
Example:<code>fqdn::www.example.org</code></td>
</tr>
</tbody>
</table>
<p><strong><span id="r-arc.3"
class="auto-hoverlink">R-ARC.3</span></strong> - BBF OUI
(<code>00256D</code>) and Private Enterprise Number (<code>3561</code>)
are reserved for use in BBF documentation and BBF prototyping and MUST
NOT be used by any entity other than BBF.</p>
<p><strong><span id="r-arc.4"
class="auto-hoverlink">R-ARC.4</span></strong> - The
“<code>proto</code>” and “<code>doc</code>” authority-scheme values MUST
NOT be used in production environments.</p>
<p>The “<code>proto</code>” and “<code>doc</code>” values are intended
only for prototyping and documentation (tutorials, examples, etc.),
respectively.</p>
<p><strong><span id="r-arc.4a"
class="auto-hoverlink">R-ARC.4a</span></strong> - If the
<code>authority-scheme</code> <code>fqdn</code> is specified, the TLS
certificates presented by this endpoint MUST contain a
<code>subjectAltName</code> extension, allowing the use of the FQDN
specified by the <code>instance-id</code> value.</p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:use-of-instance-id">2.2.2 Use of instance-id</h3>
<p><strong><span id="r-arc.5"
class="auto-hoverlink">R-ARC.5</span></strong> -
<code>instance-id</code> MUST be encoded using only the following
characters:</p>
<pre><code>    instance-id = unreserved / pct-encoded
    unreserved = ALPHA / DIGIT / &quot;-&quot; / &quot;.&quot; / &quot;_&quot;
    pct-encoded = &quot;%&quot; HEXDIG HEXDIG</code></pre>
<p>The above expression uses the Augmented Backus-Naur Form (ABNF)
notation of RFC 2234 <span class="citation" data-cites="RFC2234"><a
href="#ref-RFC2234" role="doc-biblioref">[11]</a></span>, including the
following core ABNF syntax rules defined by that specification: ALPHA
(letters), DIGIT (decimal digits), HEXDIG (hexadecimal). It is taken
from RFC 3986 <span class="citation" data-cites="RFC3986"><a
href="#ref-RFC3986" role="doc-biblioref">[15]</a></span> as the set of
unreserved characters and percent-encoded characters that are acceptable
for all components of a URI. This set is also allowed for use in URNs
RFC 2141 <span class="citation" data-cites="RFC2141"><a
href="#ref-RFC2141" role="doc-biblioref">[10]</a></span>, and all MTP
headers.</p>
<p><strong><span id="r-arc.6"
class="auto-hoverlink">R-ARC.6</span></strong> - An
<code>instance-id</code> value MUST be no more than 50 characters in
length.</p>
<p>Shorter values are preferred, as end users could be exposed to
Endpoint IDs. Long values tend to create a poor user experience when
users are exposed to them.</p>
<h2 class="auto-hoverlink" data-info="header"
id="sec:service-elements">2.3 Service Elements</h2>
<p>“Service Element” is a general term referring to the set of Objects,
Sub-Objects, Commands, Events, and Parameters that comprise a set of
functionality that is manipulated by a Controller on an Agent. An
Agent’s Service Elements are represented in a Data Model - the data
model representing an Agent’s current state is referred to as its
Instantiated Data Model, and the data model representing the Service
Elements it supports is called its Supported Data Model. An Agent’s Data
Model is referenced using Path Names.</p>
<h2 class="auto-hoverlink" data-info="header" id="sec:data-models">2.4
Data Models</h2>
<p>USP is designed to allow a Controller to manipulate Service Elements
on an Agent using a standardized description of those Service Elements.
This standardized description is known as an information model, and an
information model that is further specified for use in a particular
protocol is known as a “Data Model”.</p>
<p><em>Note: This should be understood by those familiar with CWMP. For
those unfamiliar with that protocol, a Data Model is similar to a
Management Information Base (MIB) used in the Simple Network Management
Protocol (SNMP) or YANG definitions used in NETCONF.</em></p>
<p>This version of the specification defines support for the following
Data Model(s):</p>
<ul>
<li>The Device:2 Data Model <span class="citation"
data-cites="TR-181"><a href="#ref-TR-181"
role="doc-biblioref">[3]</a></span></li>
</ul>
<p>This Data Model is specified in XML. The schema and normative
requirements for defining Objects, Parameters, Events, and Commands for
the Device:2 Data Model <span class="citation" data-cites="TR-181"><a
href="#ref-TR-181" role="doc-biblioref">[3]</a></span> are defined in
Broadband Forum TR-106 <span class="citation" data-cites="TR-106"><a
href="#ref-TR-106" role="doc-biblioref">[2]</a></span>.</p>
<p>The use of USP with any of the above data models creates some
dependencies on specific Objects and Parameters that must be included
for base functionality.</p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:instantiated-data-model">2.4.1 Instantiated Data Model</h3>
<p>An Agent’s Instantiated Data Model represents the Service Elements
(and their state) that are currently represented by the Agent. The
Instantiated Data Model includes a set of Objects, and the Sub-Objects
(“children”), Parameters, Events, and Commands associated with those
Objects.</p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:supported-data-model">2.4.2 Supported Data Model</h3>
<p>An Agent’s Supported Data Model represents the Service Elements that
an Agent understands. It includes references to the Data Model(s) that
define the Objects, Parameters, Events, and Commands implemented by the
Service Elements the Agent represents.</p>
<h3 class="auto-hoverlink" data-info="header" id="sec:objects">2.4.3
Objects</h3>
<p>Objects are data structures that are defined by their Sub-Objects,
Parameters, Events, Commands, and creation criteria. They are used to
model resources represented by the Agent. Objects may be Single-Instance
or Multi-Instance (also called a “Table”).</p>
<h4 class="auto-hoverlink" data-info="header"
id="sec:single-instance-objects">2.4.3.1 Single-Instance Objects</h4>
<p>Single-Instance Objects are not tables and do not have more than one
instance of them in the Agent. They are usually used to group Service
Element functionality together to allow for easy definition and
addressing.</p>
<h4 class="auto-hoverlink" data-info="header"
id="sec:multi-instance-objects">2.4.3.2 Multi-Instance Objects</h4>
<p>Multi-Instance” Objects are those Objects that can be the subject of
“create” and “delete” operations (using the Add and Delete Messages,
respectively), with each instance of the Object represented in the
Instantiated Data Model with an Instance Identifier (see below). A
Multi-Instance Object is also referred to as a “Table”, with each
instance of the Object referred to as a “Row”. Multi-Instance Objects
can be also the subject of a search.</p>
<h3 class="auto-hoverlink" data-info="header" id="sec:parameters">2.4.4
Parameters</h3>
<p>Parameters define the attributes or variables of an Object. They are
retrieved by a Controller using the read operations of USP and
configured using the update operations of USP (the Get and Set Messages,
respectively). Parameters have data types and are used to store
values.</p>
<h3 class="auto-hoverlink" data-info="header" id="sec:commands">2.4.5
Commands</h3>
<p>Commands define Object specific methods within the Data Model. A
Controller can invoke these methods using the Operate Message (see <a
href="#sec:defined-operations-mechanism" class="heading">Defined
Operations Mechanism</a>. Commands have associated input and output
arguments that are defined in the Data Model and used when the method is
invoked and returned.</p>
<h3 class="auto-hoverlink" data-info="header" id="sec:events">2.4.6
Events</h3>
<p>Events define Object specific notifications within the Data Model. A
Controller can subscribe to these events by creating instances of the
Subscription table, which are then sent in a Notify request by the Agent
(see <a href="#sec:notifications-and-subscriptions"
class="heading">Notifications and Subscription Mechanism</a>). Events
may also have information associated with them that are delivered in the
Notify Request - this information is defined with the Event in the Data
Model.</p>
<h2 class="auto-hoverlink" data-info="header" id="sec:path-names">2.5
Path Names</h2>
<p>A Path Name is a fully qualified reference to an Object, Object
Instance, or Parameter in an Agent’s instantiated or Supported Data
Model. The syntax for Path Names is defined in TR-106 <span
class="citation" data-cites="TR-106"><a href="#ref-TR-106"
role="doc-biblioref">[2]</a></span>.</p>
<p><strong><span id="r-arc.7"
class="auto-hoverlink">R-ARC.7</span></strong> - All USP Endpoints MUST
support the Path Name syntax as defined in TR-106 <span class="citation"
data-cites="TR-106"><a href="#ref-TR-106"
role="doc-biblioref">[2]</a></span>.</p>
<p>Path Names are represented by a hierarchy of Objects (“parents”) and
Sub-Objects (“children”), separated by the dot “.” character, ending
with a Parameter if referencing a Parameter Path. There are six
different types of Path Names used to address the data model of an
Agent:</p>
<ol type="1">
<li><p>Object Path - This is a Path Name of either a Single-Instance
Object, or the Path Name to a Multi-Instance Object (i.e., a Data Model
Table). An Object Path ends in a “.” Character (as specified in TR-106
<span class="citation" data-cites="TR-106"><a href="#ref-TR-106"
role="doc-biblioref">[2]</a></span>), except when used in a reference
Parameter (see <a href="#sec:reference-following"
class="heading">Reference Following</a>). When addressing a Table in the
Agent’s Supported Data Model that contains one or more Multi-Instance
Objects in the Path Name, the sequence “{i}” is used as a placeholder
(see <a href="#sec:the-getsupporteddm-message" class="heading">The
GetSupportedDM Message</a>).</p></li>
<li><p>Object Instance Path - This is a Path Name to a Row in a Table in
the Agent’s Instantiated Data Model (i.e., an Instance of a
Multi-Instance Object). It uses an Instance Identifier to address a
particular Instance of the Object. An Object Instance Path ends in a “.”
Character (as specified in TR-106 <span class="citation"
data-cites="TR-106"><a href="#ref-TR-106"
role="doc-biblioref">[2]</a></span>), except when used in a reference
Parameter (see <a href="#sec:reference-following"
class="heading">Reference Following</a>).</p></li>
<li><p>Parameter Path - This is a Path Name of a particular Parameter of
an Object.</p></li>
<li><p>Command Path - This is a Path Name of an Object defined <a
href="#sec:operations-and-command-path-names"
class="heading">Operation</a>.</p></li>
<li><p>Event Path - This is a Path Name of an Object defined <a
href="#sec:event-path-names" class="heading">Event</a>.</p></li>
<li><p>Search Path - This is a Path Name that contains search criteria
for addressing a set of Multi-Instance Objects and/or their Parameters.
A Search Path may contain a Search Expression or Wildcard.</p></li>
</ol>
<p>This creates two functions of Path Names: Addressing and Searching.
The first five Path Names are used for addressing a particular Object,
Parameter, Command, or Event. A Search Path uses Searching to return a
set of Object Instances and/or their Parameters. When addressing, the
expectation is that the Path Name will resolve to either 0 or 1 instance
(and depending on the context, 0 instances could be an error). When
searching, the expectation is that the Search Path will resolve to 0, 1,
or many instances (and depending on the context, 0 instances is often
not an error).</p>
<p><em>Note: When resolving a Path Name, the Agent is expected to use
locally cached information and/or information that can be obtained
rapidly and cheaply. Specifically, there is no expectation that the
Agent would issue a network request in order to resolve a Path
Name.</em></p>
<p><em>Note: Obviously only one form of addressing or searching can be
used for a given Instance Identifier in a Path Name, but different forms
of addressing can be used if more than one Instance Identifier needs to
be specified in a Path Name.</em></p>
<p>For example, the following Path Name uses Unique Key Addressing for
the Interface table but a Search Expression for the IPv4Address table to
select Enabled IPv4 Addresses associated with the “eth0” IP
Interface:</p>
<p><code>Device.IP.Interface.[Name=="eth0"].IPv4Address.[Status=="Enabled"].IPAddress</code></p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:relative-paths">2.5.1 Relative Paths</h3>
<p>Several USP Messages make use of Relative Paths to address Objects or
Parameters. A Relative Path is used to address the child Objects and
Parameters of a given Object Path or Object Instance Path. To build a
Path Name using a Relative Path, a USP Endpoint uses a specified Object
Path or Object Instance Path, and concatenates the Relative Path. This
allows some efficiency in Requests and Responses when passing large
numbers of repetitive Path Names. This Relative Path may include <a
href="#sec:using-instance-identifiers-in-path-names"
class="heading">instance identifiers</a> to Multi-Instance Objects.</p>
<p>For example, for an Object Path of:</p>
<pre><code>Device.WiFi.Radio.1.</code></pre>
<p>Relative Paths would include Parameters:</p>
<pre><code>Status
SupportedStandards
OperatingStandards</code></pre>
<p>Etc., as well as the following Sub-Object and its Parameters:</p>
<pre><code>Stats.BytesSent
Stats.BytesReceived</code></pre>
<p>Etc.</p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:using-instance-identifiers-in-path-names">2.5.2 Using Instance
Identifiers in Path Names</h3>
<h4 class="auto-hoverlink" data-info="header"
id="sec:addressing-by-instance-number">2.5.2.1 Addressing by Instance
Number</h4>
<p>Instance Number Addressing allows an Object Instance to be addressed
by using its Instance Number in the Path Name. An Instance Number is
expressed in the Path Name as a positive integer (&gt;=1) with no
additional surrounding characters. The Instance Number assigned by the
Agent is arbitrary.</p>
<p><strong><span id="r-arc.8"
class="auto-hoverlink">R-ARC.8</span></strong> - The assigned Instance
Number MUST persist unchanged until the Object Instance is subsequently
deleted (either by the USP Delete Message or through some external
mechanism). This implies that the Instance Number MUST persist across a
reboot of the Agent, and that the Agent MUST NOT allow the Instance
Number of an existing Object Instance to be modified by an external
source.</p>
<p>For example, the <code>Device.IP.Interface</code> table entry with an
Instance Number of 3 would be addressed with the following Path Name:
<code>Device.IP.Interface.3</code>.</p>
<h4 class="auto-hoverlink" data-info="header"
id="sec:addressing-by-unique-key">2.5.2.2 Addressing by Unique Key</h4>
<p>Key-based addressing allows an Object Instance to be addressed by
using a Unique Key (as defined in the Device:2 Data Model <span
class="citation" data-cites="TR-181"><a href="#ref-TR-181"
role="doc-biblioref">[3]</a></span>) in the Path Name.</p>
<p><em>Note: Controller and Agent interoperability is greatly affected
by an Agent’s implementation of Unique Keys. While this specification
does not aim to overlap its requirements to those of TR-181 <span
class="citation" data-cites="TR-181"><a href="#ref-TR-181"
role="doc-biblioref">[3]</a></span>, it is</em>
<strong><em>imperative</em></strong> <em>that an Agent implements Unique
Keys for every Multi-Instance object in its Supported Data
Model.</em></p>
<p>Unique Keys used for addressing are expressed in the Path Name by
using square brackets surrounding a string that contains the name and
value of the Unique Key Parameter using the equality operator (==).</p>
<p>For example, the <code>Device.IP.Interface</code> table has two
separate unique keys: <code>Name</code> and <code>Alias</code>. It could
be addressed with the following Path Names:</p>
<p><code>Device.IP.Interface.[Name=="eth0"]</code><br />
<code>Device.IP.Interface.[Alias=="WAN"]</code></p>
<p>If an Object has a multi-parameter unique key, then the Instance
Identifier specifies all of the key’s Parameters using the AND
(&amp;&amp;) logical operator (the Parameter order is not
significant).</p>
<p>For example, the <code>Device.NAT.PortMapping</code> table has a
multi-parameter unique key consisting of RemoteHost, ExternalPort, and
Protocol. It could be addressed with the following Path Name:</p>
<p><code>Device.NAT.PortMapping.[RemoteHost==""&amp;&amp;ExternalPort==0&amp;&amp;Protocol=="TCP"].</code></p>
<p><em>Note: Addressing by Unique Key uses the same syntax as <a
href="#sec:searching-with-expressions" class="heading">Searching with
Expressions</a>. If a multi-parameter unique key expression omits any of
the key’s Parameters then it’s a search (which might match multiple
instances) rather than an address (which can’t match multiple
instances).</em></p>
<h3 class="auto-hoverlink" data-info="header" id="sec:searching">2.5.3
Searching</h3>
<p>Searching is a means of matching 0, 1 or many instances of a
Multi-Instance Object by using the properties of Object. Searching can
be done with Expressions or Wildcards.</p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:searching-with-expressions">2.5.4 Searching with
Expressions</h3>
<p>Search Paths that use expressions are enclosed in square brackets as
the Instance Identifier within a Path Name.</p>
<p><strong><span id="r-arc.9"
class="auto-hoverlink">R-ARC.9</span></strong> - An Agent MUST return
Path Names that include all Object Instances that match the criteria of
a given Search Path.</p>
<p>The basic format of a Search Path is:</p>
<p><code>Device.IP.Interface.[&lt;expression&gt;].Status</code></p>
<p>An Expression consists of one or more Expression Components that are
concatenated by the AND (&amp;&amp;) logical operator <em>(Note: the OR
logical operator is not supported)</em>.</p>
<p>The basic format of a Search Path with the Expression element
expanded is:</p>
<p><code>Device.IP.Interface.[&lt;expression component&gt;&amp;&amp;&lt;expression component&gt;].Status</code></p>
<p>An Expression Component is a combination of an Expression Parameter
followed by an Expression Operator followed by an Expression
Constant.</p>
<p>The basic format of a Search Path with the Expression Component
element expanded is:</p>
<p><code>Device.IP.Interface.[&lt;expression parameter&gt;&lt;expression operator&gt;&lt;expression constant&gt;].Status</code></p>
<p>Further, this Relative Path can’t include any child tables.
<em>(Note: this is never necessary because any child tables that need to
be referenced in the Search Path can and should have their own
Expression)</em></p>
<p>An Expression Operator dictates how the Expression Component will be
evaluated. The supported operators are equals (==), not equals (!=),
contains (~=), less than (&lt;), greater than (&gt;), less than or equal
(&lt;=) and greater than or equal (&gt;=).</p>
<p>An Expression Parameter will always be of the type defined in the
data model. Expression operators will only evaluate for appropriate data
types. The literal value representations for all data types are found in
TR-106 <span class="citation" data-cites="TR-106"><a href="#ref-TR-106"
role="doc-biblioref">[2]</a></span>. <strong>For string and boolean
types, and also the Unknown Time dateTime value (cf. TR-106 Section
3.2.1 <span class="citation" data-cites="TR-106"><a href="#ref-TR-106"
role="doc-biblioref">[2]</a></span>), only the ‘==’ and ‘!=’ operators
are valid.</strong></p>
<p>The ‘~=’ operator is only valid for comma-separated lists. It is used
to check whether a list contains a certain element using an exact match
of the element. The Expression Constant used in the Search Expression
must be of the same type as the values in the list. For example, for a
list of integers, the Expression Constant must also be an integer.</p>
<p><em>Note: Literal values are conceptually converted to a suitable
internal representation before comparison. For example, <code>int</code>
values <code>123</code>, <code>+123</code> and <code>0123</code> all
represent the same value, and so do <code>boolean</code> values
<code>1</code> and <code>true</code>.</em></p>
<p>The Expression Constant is the value that the Expression Parameter is
being evaluated against; Expression Parameters must match the type as
defined for the associated Parameter in the Device:2 Data Model <span
class="citation" data-cites="TR-181"><a href="#ref-TR-181"
role="doc-biblioref">[3]</a></span>.</p>
<p><em>Note: String values are enclosed in double quotes. In order to
allow a string value to contain double quotes, quote characters can be
percent-escaped as %22 (double quote). Therefore, a literal percent
character has to be quoted as %25.</em></p>
<p>The use of whitespace on either side of an Expression Operator is
allowed, but its support is not required. Controllers cannot assume that
an Agent tolerates whitespace. An example of an Expression with
whitespace would be <code>[Type == "Normal"]</code> (which would be
<code>[Type=="Normal"]</code> without whitespace).</p>
<p><strong><span id="r-arc.9a"
class="auto-hoverlink">R-ARC.9a</span></strong> - Agents SHOULD tolerate
whitespace on either side of an Expression Operator.</p>
<p><strong><span id="r-arc.9b"
class="auto-hoverlink">R-ARC.9b</span></strong> - Controllers SHOULD NOT
include whitespace on either side of an Expression Operator.</p>
<h5 class="auto-hoverlink" data-info="header"
id="sec:search-expression-examples">2.5.4.0.1 Search Expression
Examples</h5>
<p><em>Valid Searches:</em></p>
<ul>
<li><p>Status for all IP Interfaces with a “Normal” type:</p>
<p><code>Device.IP.Interface.[Type=="Normal"].Status</code></p></li>
<li><p>IPv4 Addresses for all IP Interfaces with a Normal type and a
Static addressing type:</p>
<p><code>Device.IP.Interface.[Type=="Normal"].IPv4Address.[AddressingType=="Static"].IPAddress</code></p></li>
<li><p>IPv4 Addresses for all IP Interfaces with a Normal type and
Static addressing type that have at least 1 Error Sent:</p>
<p><code>Device.IP.Interface.[Type=="Normal"&amp;&amp;Stats.ErrorsSent&gt;0].IPv4Address.[AddressingType=="Static"].IPAddress</code></p></li>
<li><p>Current profiles used by all DSL lines which are enabled:</p>
<p><code>Device.DSL.Line.[Enable==true].CurrentProfile</code></p>
<p>or</p>
<p><code>Device.DSL.Line.[Enable==1].CurrentProfile</code></p></li>
<li><p>All IPv6 Addresses of all interfaces with a lifetime expiring
before 2021-06-06 08:00 UTC:</p>
<p><code>Device.IP.Interface.*.IPv6Address.[ValidLifetime&lt;2021-06-06T08:00:00Z].IPAddress</code></p></li>
<li><p>All Parameters of all connected USB devices of class 0x08 (Mass
Storage Device):</p>
<p><code>Device.USB.USBHosts.Host.*.Device.[DeviceClass==08].</code></p></li>
<li><p>All Parameters of all PCP servers with IPv6Firewall
capabilities:</p>
<p><code>Device.PCP.Client.*.Server.[Capabilities~="IPv6Firewall"].</code></p></li>
<li><p>All Parameters of all PeriodicStatistics SampleSets that
collected data for 5 seconds:</p>
<p><code>Device.PeriodicStatistics.SampleSet.[SampleSeconds~=5].</code></p></li>
</ul>
<p><em>Searches that are NOT VALID:</em></p>
<ul>
<li><p>Invalid because the Expression is empty:</p>
<p><code>Device.IP.Interface.[].</code></p></li>
<li><p>Invalid because the Expression Component has an Expression
Parameter that descends into a child table (always need to use a
separate Expression Variable for each child table instance):</p>
<p><code>Device.IP.Interface.[Type=="Normal"&amp;&amp;IPv4Address.*.AddressingType=="Static"].Status</code></p></li>
<li><p>Invalid because the search expression uses curly brackets:</p>
<p><code>Device.IP.Interface.{Type=="Normal"}.Status</code></p></li>
<li><p>Invalid because the <code>Enable</code> Parameter is of type
<code>boolean</code> and not a <code>string</code> or derived from
<code>string</code>:</p>
<p><code>Device.DSL.Line.[Enable=="true"].CurrentProfile</code></p></li>
</ul>
<h3 class="auto-hoverlink" data-info="header"
id="sec:searching-by-wildcard">2.5.5 Searching by Wildcard</h3>
<p>Wildcard-based searching is a means of matching all currently
existing Instances (whether that be 0, 1 or many instances) of a
Multi-Instance Object by using a wildcard character “*” in place of the
Instance Identifier.</p>
<p><strong><span id="r-arc.10"
class="auto-hoverlink">R-ARC.10</span></strong> - An Agent MUST return
Path Names that include all Object Instances that are matched by the use
of a Wildcard.</p>
<p>Examples:</p>
<p>All Parameters for all IP Interfaces that currently exist</p>
<p><code>Device.IP.Interface.*.</code></p>
<p>Type of each IP Interface that currently exists</p>
<p><code>Device.IP.Interface.*.Type</code></p>
<h2 class="auto-hoverlink" data-info="header"
id="sec:other-path-decorators">2.6 Other Path Decorators</h2>
<h3 class="auto-hoverlink" data-info="header"
id="sec:reference-following">2.6.1 Reference Following</h3>
<p>The Device:2 Data Model <span class="citation" data-cites="TR-181"><a
href="#ref-TR-181" role="doc-biblioref">[3]</a></span> contains
Parameters that reference other Parameters or Objects. The Reference
Following mechanism allows references to Objects (not Parameters) to be
followed from inside a single Path Name. Reference Following is
indicated by a “+” character after the Parameter Path, referencing the
Object followed by a “.”, optionally followed by a Relative Object or
Parameter Path that are children of the Referenced Object.</p>
<p>For example, <code>Device.NAT.PortMapping.{i}.Interface</code>
references an IP Interface Object
(<code>Device.IP.Interface.{i}.</code>) and that Object has a Parameter
called “<code>Name</code>”. With Reference Following, a Path Name of
<code>Device.NAT.PortMapping.1.Interface+.Name</code> references the
“<code>Name</code>” Parameter of the <code>Interface</code> Object that
the <code>PortMapping</code> is associated with (i.e. it is the
equivalent of using <code>Device.IP.Interface.1.Name</code> as the Path
Name).</p>
<p>The steps that are executed by the Agent when following the reference
in this example would be:</p>
<ol type="1">
<li><p>Retrieve the appropriate instance of the <code>PortMapping</code>
Object based on the Instance Number Addressing information</p></li>
<li><p>Retrieve the value of the reference Parameter that contains the
reference, Interface, which in this case has the value
“<code>Device.IP.Interface.1</code>”</p></li>
<li><p>Replace the preceding Path Name
(<code>Device.NAT.PortMapping.1.Interface+</code>) with the value
retrieved in Step 2</p></li>
<li><p>Append the remainder of the Path Name (<code>.Name</code>), which
builds the Path Name: <code>Device.IP.Interface.1.Name</code></p></li>
<li><p>Use <code>Device.IP.Interface.1.Name</code> as the Path Name for
the action</p></li>
</ol>
<p><em>Note: It should be noted that according to the Device:2 Schema
<span class="citation" data-cites="TR-106"><a href="#ref-TR-106"
role="doc-biblioref">[2]</a></span>, reference Parameters:</em></p>
<ul>
<li><em>Always contain Path Names (not Search Expressions)</em></li>
<li><em>When configured, can be configured using Path Names using
Instance Number Addressing or Unique-Key Addressing, however:</em></li>
<li><em>When the value of a reference Parameter is read, all Instance
Identifiers are returned as Instance Numbers.</em></li>
</ul>
<p><strong><span id="r-arc.11"
class="auto-hoverlink">R-ARC.11</span></strong> - A USP Agent MUST
support the ability to use Key-based addressing in reference values.</p>
<p>For example, the following Path Names might illustrate a reference to
the same Object (defined as having the Parameter named
<code>KeyParam</code> as unique key) instance using an Instance Number
and then a key value:</p>
<ul>
<li>Object.SomeReferenceParameter = “Object.FooObject.5”</li>
<li>Object.SomeReferenceParameter =
‘Object.FooObject.[KeyParam==“KeyValueForInstance5”]’</li>
</ul>
<p>In the first example, the reference points to the FooObject with
Instance Number 5. In the second example, the reference points to the
FooObject with a <code>KeyParam</code> value of
“KeyValueForInstance5”.</p>
<p><strong><span id="r-arc.12"
class="auto-hoverlink">R-ARC.12</span></strong> - The following
requirements relate to reference types and the associated Agent
behavior:</p>
<ul>
<li>An Agent MUST reject an attempt to set a strong reference Parameter
if the new value does not reference an existing Parameter or
Object.</li>
<li>An Agent MUST NOT reject an attempt to set a weak reference
Parameter because the new value does not reference an existing Parameter
or Object.</li>
<li>An Agent MUST change the value of a non-list-valued strong reference
Parameter to a null reference when a referenced Parameter or Object is
deleted.</li>
<li>An Agent MUST remove the corresponding list item from a list-valued
strong reference Parameter when a referenced Parameter or Object is
deleted.</li>
<li>An Agent MUST NOT change the value of a weak reference Parameter
when a referenced Parameter or Object is deleted.</li>
</ul>
<h4 class="auto-hoverlink" data-info="header"
id="sec:list-of-references">2.6.1.1 List of References</h4>
<p>The USP data models have Parameters whose values contain a list of
references to other Parameters or Objects. This section explains how the
Reference Following mechanism allows those references to be followed
from inside a single Path Name. The Reference Following syntax as
defined above still applies, but the “<code>+</code>” character is
preceded by a means of referencing a list item or items.</p>
<ul>
<li><p>The additional syntax consists of a “<code>#</code>” character
followed by a list item number (1-indexed), which is placed between the
Parameter name and the “<code>+</code>” character.</p>
<ul>
<li>The “<code>#</code>” and list item number are optional. If they are
omitted, the first list item is used, i.e.,
“<code>ReferenceParameter+</code>” means the same as
“<code>ReferenceParameter#1+</code>”.</li>
</ul></li>
<li><p>To follow <em>all</em> references in the list, use a wildcard
(“<code>*</code>”) character instead of a list item number, i.e.,
“<code>ReferenceParameter#*+</code>”.</p></li>
</ul>
<p>For example, <code>Device.WiFi.SSID.{i}.LowerLayers</code> references
a list of Wi-Fi Radio Object (defined as
<code>Device.WiFi.Radio.{i}.</code>) Instances that are associated with
the SSID. This Object has a <code>Name</code> Parameter; so when
following the first reference in the list of references a Path Name of
<code>Device.WiFi.SSID.1.LowerLayers#1+.Name</code> references the Name
of the Wi-Fi Radio associated with this SSID Object Instance.</p>
<p>The steps that are executed by the Agent when following the reference
in this example would be:</p>
<ol type="1">
<li><p>Retrieve the appropriate <code>Device.WiFi.SSID.{i}</code>
instance based on the Instance Number Addressing information</p></li>
<li><p>Retrieve the value of the LowerLayers Parameter, which in this
case has a value of
“<code>Device.WiFi.Radio.1, Device.WiFi.Radio.2</code>”</p></li>
<li><p>Retrieve the first list item within the value retrieved in Step 2
(i.e., “<code>Device.WiFi.Radio.1</code>”)</p></li>
<li><p>Replace the preceding Path Name
(<code>Device.WiFi.SSID.1.LowerLayers#1+</code>) with the value
retrieved in Step 3</p></li>
<li><p>Append the remainder of the Path Name (<code>.Name</code>),
resulting in a Path Name of:
<code>Device.WiFi.Radio.1.Name</code></p></li>
<li><p>Use <code>Device.WiFi.Radio.1.Name</code> as the Path Name for
the action</p></li>
</ol>
<h4 class="auto-hoverlink" data-info="header"
id="sec:search-expressions-and-reference-following">2.6.1.2 Search
Expressions and Reference Following</h4>
<p>The Reference Following and Search Expression mechanisms can be
combined.</p>
<p>For example, reference the Signal Strength of all Wi-Fi Associated
Devices using the “ac” Operating Standard on the “MyHome” SSID, you
would use the Path Name:</p>
<p><code>Device.WiFi.AccessPoint.[SSIDReference+.SSID=="MyHome"].AssociatedDevice.[OperatingStandard=="ac"].SignalStrength</code></p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:operations-and-command-path-names">2.6.2 Operations and Command
Path Names</h3>
<p>The <a href="#sec:operate" class="heading">Operate Message</a> allows
a USP Controller to execute Commands defined in the USP data models.
Commands are synchronous or asynchronous operations that don’t fall into
the typical REST-based concepts of CRUD-N that have been incorporated
into the protocol as specific Messages. Commands are addressed like
Parameter Paths that end with parentheses “()” to symbolize that it is a
Command.</p>
<p>For example:
<code>Device.IP.Interface.[Name=="eth0"].Reset()</code></p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:event-path-names">2.6.3 Event Path Names</h3>
<p>The Notify request allows a type of generic event (called Event)
message that allows a USP Agent to emit events defined in the USP data
models. Events are defined in and related to Objects in the USP data
models like commands. Events are addressed like Parameter Paths that end
with an exclamation point “!” to symbolize that it is an Event.</p>
<p>For example: <code>Device.Boot!</code></p>
<h2 class="auto-hoverlink" data-info="header"
id="sec:data-model-path-grammar">2.7 Data Model Path Grammar</h2>
<p>Expressed as a <a
href="https://en.wikipedia.org/wiki/Backus-Naur_form">Backus-Naur Form
(BNF)</a> for context-free grammars, the Path Name lexical rules for
referencing the Instantiated Data Model are:</p>
<pre><code>idmpath   ::= objpath | parampath | cmdpath | evntpath
objpath   ::= name &#39;.&#39; (name ((&#39;.&#39; inst)|(reffollow &#39;.&#39; name) )? &#39;.&#39;)*
parampath ::= objpath name
cmdpath   ::= objpath  name &#39;()&#39;
evntpath  ::= objpath  name &#39;!&#39;
inst      ::= posnum | expr | &#39;*&#39;
expr      ::= &#39;[&#39; (exprcomp ( &#39;&amp;&amp;&#39; exprcomp )*) &#39;]&#39;
exprcomp  ::= relpath oper value
relpath   ::= name (reffollow? &#39;.&#39; name )*
reffollow ::=  ( &#39;#&#39; (posnum | &#39;*&#39;) &#39;+&#39; )|  &#39;+&#39;
oper      ::= &#39;==&#39; | &#39;!=&#39; | &#39;~=&#39; | &#39;&lt;&#39; | &#39;&gt;&#39; | &#39;&lt;=&#39; | &#39;&gt;=&#39;
value     ::= literal | number
name      ::= [A-Za-z_] [A-Za-z_0-9]*
literal   ::= &#39;&quot;&#39; [^&quot;]* &#39;&quot;&#39;
posnum    ::= [1-9] [0-9]*
number    ::= &#39;0&#39; | ( &#39;-&#39;? posnum )</code></pre>
<p>The Path Name lexical rules for referencing the Supported Data Model
are:</p>
<pre><code>sdmpath   ::= name &#39;.&#39; ( name &#39;.&#39; ( ( posnum | &#39;{i}&#39; ) &#39;.&#39; )? )* name?
name      ::= [A-Za-z_] [A-Za-z_0-9]*
posnum    ::= [1-9] [0-9]*</code></pre>
<h3 class="auto-hoverlink" data-info="header"
id="sec:bnf-diagrams-for-instantiated-data-model">2.7.1 BNF Diagrams for
Instantiated Data Model</h3>
<p><strong><span id="bnf:idmpath"
class="auto-hoverlink">idmpath</span></strong>:</p>
<p><img src="architecture/diagram/idmpath.png" /></p>
<div class="ebnf">
<p>idmpath ::= objpath | parampath | cmdpath | evntpath</p>
</div>
<p><br />
<strong><span id="bnf:objpath"
class="auto-hoverlink">objpath</span></strong>:</p>
<p><img src="architecture/diagram/objpath.png" /></p>
<div class="ebnf">
<p>objpath ::= name ‘.’ ( name ( ‘.’ inst | reffollow ‘.’ name)? ‘.’
)*</p>
</div>
<p>referenced by:</p>
<ul>
<li><a href="#bnf:cmdpath">cmdpath</a></li>
<li><a href="#bnf:evntpath">evntpath</a></li>
<li><a href="#bnf:idmpath">idmpath</a></li>
<li><a href="#bnf:parampath">parampath</a></li>
</ul>
<p><br />
<strong><span id="bnf:parampath"
class="auto-hoverlink">parampath</span></strong>:</p>
<p><img src="architecture/diagram/parampath.png" /></p>
<div class="ebnf">
<p>parampath ::= objpath name</p>
</div>
<p>referenced by:</p>
<ul>
<li><a href="#bnf:idmpath">idmpath</a></li>
</ul>
<p><br />
<strong><span id="bnf:cmdpath"
class="auto-hoverlink">cmdpath</span></strong>:</p>
<p><img src="architecture/diagram/cmdpath.png" /></p>
<div class="ebnf">
<p>cmdpath ::= objpath name ‘()’</p>
</div>
<p>referenced by:</p>
<ul>
<li><a href="#bnf:idmpath">idmpath</a></li>
</ul>
<p><br />
<strong><span id="bnf:evntpath"
class="auto-hoverlink">evntpath</span></strong>:</p>
<p><img src="architecture/diagram/evntpath.png" /></p>
<div class="ebnf">
<p>evntpath ::= objpath name ‘!’</p>
</div>
<p>referenced by:</p>
<ul>
<li><a href="#bnf:idmpath">idmpath</a></li>
</ul>
<p><br />
<strong><span id="bnf:inst"
class="auto-hoverlink">inst</span></strong>:</p>
<p><img src="architecture/diagram/inst.png" /></p>
<div class="ebnf">
<p>inst ::= posnum | expr | ’*’</p>
</div>
<p>referenced by:</p>
<ul>
<li><a href="#bnf:objpath">objpath</a></li>
</ul>
<p><br />
<strong><span id="bnf:expr"
class="auto-hoverlink">expr</span></strong>:</p>
<p><img src="architecture/diagram/expr.png" /></p>
<div class="ebnf">
<p>expr ::= ‘[’ exprcomp ( ’&amp;&amp;’ exprcomp )* ’]’</p>
</div>
<p>referenced by:</p>
<ul>
<li><a href="#bnf:inst">inst</a></li>
</ul>
<p><br />
<strong><span id="bnf:exprcomp"
class="auto-hoverlink">exprcomp</span></strong>:</p>
<p><img src="architecture/diagram/exprcomp.png" /></p>
<div class="ebnf">
<p>exprcomp ::= relpath oper value</p>
</div>
<p>referenced by:</p>
<ul>
<li><a href="#bnf:expr">expr</a></li>
</ul>
<p><br />
<strong><span id="bnf:relpath"
class="auto-hoverlink">relpath</span></strong>:</p>
<p><img src="architecture/diagram/relpath.png" /></p>
<div class="ebnf">
<p>relpath ::= name ( reffollow? ‘.’ name )*</p>
</div>
<p>referenced by:</p>
<ul>
<li><a href="#bnf:exprcomp">exprcomp</a></li>
</ul>
<p><br />
<strong><span id="bnf:reffollow"
class="auto-hoverlink">reffollow</span></strong>:</p>
<p><img src="architecture/diagram/reffollow.png" /></p>
<div class="ebnf">
<p>reffollow ::= ( ‘#’ ( posnum | ’*’ ) )? ‘+’</p>
</div>
<p>referenced by:</p>
<ul>
<li><a href="#bnf:objpath">objpath</a></li>
<li><a href="#bnf:relpath">relpath</a></li>
</ul>
<p><br />
<strong><span id="bnf:oper"
class="auto-hoverlink">oper</span></strong>:</p>
<p><img src="architecture/diagram/oper.png" /></p>
<div class="ebnf">
<p>oper ::= ‘==’ | ‘!=’ | ‘~=’ | ‘&lt;’ | ‘&gt;’ | ‘&lt;=’ | ‘&gt;=’</p>
</div>
<p>referenced by:</p>
<ul>
<li><a href="#bnf:exprcomp">exprcomp</a></li>
</ul>
<p><br />
<strong><span id="bnf:value"
class="auto-hoverlink">value</span></strong>:</p>
<p><img src="architecture/diagram/value.png" /></p>
<div class="ebnf">
<p>value ::= literal | number</p>
</div>
<p>referenced by:</p>
<ul>
<li><a href="#bnf:exprcomp">exprcomp</a></li>
</ul>
<p><br />
<strong><span id="bnf:name"
class="auto-hoverlink">name</span></strong>:</p>
<p><img src="architecture/diagram/name.png" /></p>
<div class="ebnf">
<p>name ::= [A-Za-z_] [A-Za-z_0-9]*</p>
</div>
<p>referenced by:</p>
<ul>
<li><a href="#bnf:cmdpath">cmdpath</a></li>
<li><a href="#bnf:evntpath">evntpath</a></li>
<li><a href="#bnf:objpath">objpath</a></li>
<li><a href="#bnf:parampath">parampath</a></li>
<li><a href="#bnf:relpath">relpath</a></li>
</ul>
<p><br />
<strong><span id="bnf:literal"
class="auto-hoverlink">literal</span></strong>:</p>
<p><img src="architecture/diagram/literal.png" /></p>
<div class="ebnf">
<p>literal ::= ‘“’ [^"]* ‘“’</p>
</div>
<p>referenced by:</p>
<ul>
<li><a href="#bnf:value">value</a></li>
</ul>
<p><br />
<strong><span id="bnf:number"
class="auto-hoverlink">number</span></strong>:</p>
<p><img src="architecture/diagram/number.png" /></p>
<div class="ebnf">
<p>number ::= ‘0’ | ‘-’? posnum</p>
</div>
<p>referenced by:</p>
<ul>
<li><a href="#bnf:value">value</a></li>
</ul>
<p><br />
<strong><span id="bnf:posnum"
class="auto-hoverlink">posnum</span></strong>:</p>
<p><img src="architecture/diagram/posnum.png" /></p>
<div class="ebnf">
<p>posnum ::= [1-9] [0-9]*</p>
</div>
<p>referenced by:</p>
<ul>
<li><a href="#bnf:inst">inst</a></li>
<li><a href="#bnf:number">number</a></li>
<li><a href="#bnf:reffollow">reffollow</a></li>
</ul>
<h3 class="auto-hoverlink" data-info="header"
id="sec:bnf-diagrams-for-supported-data-model">2.7.2 BNF Diagrams for
Supported Data Model</h3>
<p><strong><span id="bnf:sdmpath"
class="auto-hoverlink">sdmpath</span></strong>:</p>
<p><img src="architecture/diagram/sdmpath.png" /></p>
<div class="ebnf">
<p>sdmpath ::= name ‘.’ ( name ‘.’ ( ( posnum | ‘{i}’ ) ‘.’ )? )*
name?</p>
</div>
<p><br />
<strong><span id="bnf:name-1"
class="auto-hoverlink">name</span></strong>:</p>
<p><img src="architecture/diagram/name.png" /></p>
<div class="ebnf">
<p>name ::= [A-Za-z_] [A-Za-z_0-9]*</p>
</div>
<p>referenced by:</p>
<ul>
<li><a href="#bnf:sdmpath">sdmpath</a></li>
</ul>
<p><br />
<strong><span id="bnf:posnum-1"
class="auto-hoverlink">posnum</span></strong>:</p>
<p><img src="architecture/diagram/posnum.png" /></p>
<div class="ebnf">
<p>posnum ::= [1-9] [0-9]*</p>
</div>
<p>referenced by:</p>
<ul>
<li><a href="#bnf:sdmpath">sdmpath</a></li>
</ul>
<h1 class="auto-hoverlink" data-info="header" id="sec:discovery">3
Discovery and Advertisement</h1>
<p>Discovery is the process by which USP Endpoints learn the USP
properties and MTP connection details of another Endpoint, either for
sending USP Messages in the context of an existing relationship (where
the Controller’s USP Endpoint Identifier, credentials, and authorized
Role are all known to the Agent) or for the establishment of a new
relationship.</p>
<p>Advertisement is the process by which USP Endpoints make their
presence known (or USP Endpoint presence is made known) to other USP
Endpoints.</p>
<h2 class="auto-hoverlink" data-info="header"
id="sec:controller-information">3.1 Controller Information</h2>
<p>An Agent that has a USP relationship with a Controller needs to know
that Controller’s Endpoint Identifier, credentials, and authorized
Role.</p>
<p>An Agent that has a USP relationship with a Controller needs to
obtain information that allows it to determine at least one MTP, IP
address, port, and resource path (if required by the MTP) of the
Controller. This may be a URL with all of these components, a FQDN that
resolves to provide all of these components via DNS-SD records, or mDNS
discovery in the LAN.</p>
<p>Example mechanisms for configuration include but are not limited
to:</p>
<ul>
<li>Pre-configured in firmware</li>
<li>Configured by an already-known-and-trusted Controller</li>
<li>Configured through a separate bootstrap mechanism such as a user
interface or other management interface.</li>
<li><a href="#sec:using-dhcp" class="heading">DHCP</a>, <a
href="#sec:using-dns" class="heading">DNS</a>, or <a
href="#sec:using-mdns" class="heading">mDNS</a>.</li>
</ul>
<p><strong><span id="r-dis.0"
class="auto-hoverlink">R-DIS.0</span></strong> - An Agent that supports
USP configuration of Controllers MUST implement the
<code>Device.LocalAgent.Controller</code> Object as defined in the
Device:2 Data Model <span class="citation" data-cites="TR-181"><a
href="#ref-TR-181" role="doc-biblioref">[3]</a></span>.</p>
<p>The Agent can be pre-configured with trusted root certificates or
trusted certificates to allow authentication of Controllers. Other trust
models are also possible, where an Agent without a current Controller
association will trust the first discovered Controller, or where the
Agent has a UI that allows a User to indicate whether a discovered
Controller is authorized to configure that Agent.</p>
<h2 class="auto-hoverlink" data-info="header"
id="sec:required-agent-information">3.2 Required Agent Information</h2>
<p>A Controller that has a relationship with an Agent needs to know the
Agent’s Endpoint Identifier, connectivity information for the Agent’s
MTP(s), and credentials.</p>
<p>Controllers acquire this information upon initial connection by an
Agent, though a LAN based Controller may acquire an Agent’s MTP
information through mDNS Discovery. It is each Controller’s
responsibility to maintain a record of known Agents.</p>
<h2 class="auto-hoverlink" data-info="header" id="sec:using-dhcp">3.3
Use of DHCP for Acquiring Controller Information</h2>
<p>DHCP can be employed as a method for Agents to discover Controllers.
The DHCPv4 Vendor-Identifying Vendor-Specific Information Option <span
class="citation" data-cites="RFC3925"><a href="#ref-RFC3925"
role="doc-biblioref">[14]</a></span> (option code 125) and DHCPv6
Vendor-specific Information Option <span class="citation"
data-cites="RFC3315"><a href="#ref-RFC3315"
role="doc-biblioref">[13]</a></span> (option code 17) can be used to
provide information to Agents about a single Controller. The options
that may be returned by DNS are shown below. Description of these
options can be found in the Device:2 Data Model <span class="citation"
data-cites="TR-181"><a href="#ref-TR-181"
role="doc-biblioref">[3]</a></span>.</p>
<p><strong><span id="r-dis.1"
class="auto-hoverlink">R-DIS.1</span></strong> - If an Agent is
configured to request Controller DHCP information, the Agent MUST
include in its DHCPv4 requests a DHCPv4 V-I Vendor Class Option (option
124) and in its DHCPv6 requests a DHCPv6 Vendor Class (option 16). This
option MUST include the Broadband Forum Enterprise Number
(<code>3561</code> decimal, <code>0x0DE9</code> hex) as an
enterprise-number, and the string “<code>usp</code>” (all lower case) in
a vendor-class-data instance associated with this enterprise-number.</p>
<p><strong><span id="r-dis.1a"
class="auto-hoverlink">R-DIS.1a</span></strong> - The Agent MUST decode
all received options as strings (provisioning code, wait interval, and
interval multiplier are not decoded as numeric fields).</p>
<p><strong><span id="r-dis.1b"
class="auto-hoverlink">R-DIS.1b</span></strong> - The Agent MUST
interpret a received URL or FQDN of the Controller as either an absolute
URL or FQDN.</p>
<p><strong><span id="r-dis.1c"
class="auto-hoverlink">R-DIS.1c</span></strong> - If the Agent receives
an encapsulated option value that is null terminated, the Agent MUST
accept the value provided, and MUST NOT interpret the null character as
part of the value.</p>
<p>The Role to associate with a DHCP-discovered Controller is
programmatically determined (see <a href="#sec:auth"
class="heading">Authentication and Authorization</a>).</p>
<p><em>Note: Requirement R-DIS.2 was removed in USP 1.2.</em></p>
<p>See <a href="#sec:using-dns" class="heading">Using DNS</a> for
requirements on resolving URLs and FQDNs provided by DHCP.</p>
<p>ISPs are advised to limit the use of DHCP for configuration of a
Controller to situations in which the security of the link between the
DHCP server and the Agent can be assured by the service provider. Since
DHCP does not itself incorporate a security mechanism, it is a good idea
to use pre-configured certificates or other means of establishing trust
between the Agent and a Controller discovered by DHCP.</p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:dhcp-options-for-controller-discovery">3.3.1 DHCP Options for
Controller Discovery</h3>
<table>
<colgroup>
<col style="width: 25%" />
<col style="width: 25%" />
<col style="width: 27%" />
<col style="width: 20%" />
</colgroup>
<thead>
<tr class="header">
<th style="text-align: right;">Encapsulated Option</th>
<th style="text-align: center;">DHCPv4 Option 125</th>
<th style="text-align: center;">DHCPv6 Option 17</th>
<th style="text-align: left;">Parameter in the Device:2 Data Model <span
class="citation" data-cites="TR-181"><a href="#ref-TR-181"
role="doc-biblioref">[3]</a></span></th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: right;">URL or FQDN of the Controller</td>
<td style="text-align: center;"><code>25</code></td>
<td style="text-align: center;"><code>25</code></td>
<td style="text-align: left;"><code>Dependent on MTP</code></td>
</tr>
<tr class="even">
<td style="text-align: right;">Provisioning code</td>
<td style="text-align: center;"><code>26</code></td>
<td style="text-align: center;"><code>26</code></td>
<td
style="text-align: left;"><code>Device.LocalAgent.Controller.{i}.ProvisioningCode</code></td>
</tr>
<tr class="odd">
<td style="text-align: right;">USP retry minimum wait interval</td>
<td style="text-align: center;"><code>27</code></td>
<td style="text-align: center;"><code>27</code></td>
<td
style="text-align: left;"><code>Device.LocalAgent.Controller.{i}.USPNotifRetryMinimumWaitInterval</code></td>
</tr>
<tr class="even">
<td style="text-align: right;">USP retry interval multiplier</td>
<td style="text-align: center;"><code>28</code></td>
<td style="text-align: center;"><code>28</code></td>
<td
style="text-align: left;"><code>Device.LocalAgent.Controller.{i}.USPNotifRetryIntervalMultiplier</code></td>
</tr>
<tr class="odd">
<td style="text-align: right;">Endpoint ID of the Controller</td>
<td style="text-align: center;"><code>29</code></td>
<td style="text-align: center;"><code>29</code></td>
<td
style="text-align: left;"><code>Device.LocalAgent.Controller.{i}.EndpointID</code></td>
</tr>
</tbody>
</table>
<h2 class="auto-hoverlink" data-info="header" id="sec:gatewayinfo">3.4
Use of DHCP for Exchanging GatewayInfo</h2>
<p>This section contains a set of USP requirements related to a
mechanism that was originally defined in the CPE WAN Management Protocol
<span class="citation" data-cites="TR-069"><a href="#ref-TR-069"
role="doc-biblioref">[1]</a></span> (CWMP), which provides a way for a
CWMP Gateway and an End Device to exchange information via DHCP options
to populate data model objects with their reciprocal information. The
purpose of populating this information is to provides an ACS or USP
Controller with the ability to determine whether the Gateway and Device
are on the same LAN. The USP requirements defined in this section
identify what USP-enabled devices (Gateways and End Devices) need to do
to interoperate with CWMP-enabled devices without changing any CWMP
functionality, so it is mostly a replication of those CWMP requirements
from a USP-enabled device perspective.</p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:exchanging-dhcp-options">3.4.1 Exchanging DHCP Options</h3>
<p>This section outlines the DHCP information USP Agents exchange to
provide details about the devices on the LAN, as well as the Service
Elements that are updated. This allows a USP Agent to recognize a CWMP
Client that supports the Device-Gateway Association within the LAN, and
a CWMP Client to recognize a USP Agent.</p>
<p><strong><span id="r-dis.2a"
class="auto-hoverlink">R-DIS.2a</span></strong> - When an Agent sends a
DHCPv4 requests (DHCPDISCOVER, DHCPREQUEST, and DHCPINFORM) or DHCPv6
requests (SOLICIT, REQUEST, RENEW, and INFORMATION-REQUEST) it MUST
include the Encapsulation Options for requests below.</p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:dhcp-encapsulated-vendor-specific-option-data-fields-for-dhcp-requests">3.4.2
DHCP Encapsulated Vendor-Specific Option-Data fields for DHCP
requests</h3>
<table>
<colgroup>
<col style="width: 25%" />
<col style="width: 25%" />
<col style="width: 27%" />
<col style="width: 22%" />
</colgroup>
<thead>
<tr class="header">
<th style="text-align: right;">Encapsulated Option</th>
<th style="text-align: center;">DHCPv4 Option 125</th>
<th style="text-align: center;">DHCPv6 Option 17</th>
<th style="text-align: left;">Parameter in the Device:2 Data Model <span
class="citation" data-cites="TR-181"><a href="#ref-TR-181"
role="doc-biblioref">[3]</a></span></th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: right;">DeviceManufacturerOUI</td>
<td style="text-align: center;"><code>1</code></td>
<td style="text-align: center;"><code>11</code></td>
<td
style="text-align: left;"><code>Device.DeviceInfo.ManufacturerOUI</code></td>
</tr>
<tr class="even">
<td style="text-align: right;">DeviceSerialNumber</td>
<td style="text-align: center;"><code>2</code></td>
<td style="text-align: center;"><code>12</code></td>
<td
style="text-align: left;"><code>Device.DeviceInfo.SerialNumber</code></td>
</tr>
<tr class="odd">
<td style="text-align: right;">DeviceProductClass</td>
<td style="text-align: center;"><code>3</code></td>
<td style="text-align: center;"><code>13</code></td>
<td
style="text-align: left;"><code>Device.DeviceInfo.ProductClass</code></td>
</tr>
</tbody>
</table>
<p>These Encapsulated Options are carried in DHCPv4 V-I Vendor Class
Option (option 125) or DHCPv6 V-I Vendor Class Option (option 17) with
an element identified with the IANA Enterprise Number for the Broadband
Forum that follows the format defined below. The IANA Enterprise Number
for the Broadband Forum is 3561 in decimal (the ADSL Forum entry in the
IANA Private Enterprise Numbers registry).</p>
<p><strong><span id="r-dis.2b"
class="auto-hoverlink">R-DIS.2b</span></strong> - If an Agent recieves
the encapsulation options for requests above, then it MUST respond with
the Encapsulated Options for a response in the DHCPv4 responses
(DHCPOFFER and DHCPACK) and DHCPv6 responses (ADVERTISE and REPLY)
below. The responses are only included if the request options are
recieved.</p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:dhcp-encapsulated-vendor-specific-option-data-fields-for-agent">3.4.3
DHCP Encapsulated Vendor-Specific Option-Data fields for Agent</h3>
<table>
<colgroup>
<col style="width: 25%" />
<col style="width: 25%" />
<col style="width: 27%" />
<col style="width: 22%" />
</colgroup>
<thead>
<tr class="header">
<th style="text-align: right;">Encapsulated Option</th>
<th style="text-align: center;">DHCPv4 Option 125</th>
<th style="text-align: center;">DHCPv6 Option 17</th>
<th style="text-align: left;">Parameter in the Device:2 Data Model <span
class="citation" data-cites="TR-181"><a href="#ref-TR-181"
role="doc-biblioref">[3]</a></span></th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: right;">DeviceManufacturerOUI</td>
<td style="text-align: center;"><code>4</code></td>
<td style="text-align: center;"><code>14</code></td>
<td
style="text-align: left;"><code>Device.DeviceInfo.ManufacturerOUI</code></td>
</tr>
<tr class="even">
<td style="text-align: right;">DeviceSerialNumber</td>
<td style="text-align: center;"><code>5</code></td>
<td style="text-align: center;"><code>15</code></td>
<td
style="text-align: left;"><code>Device.DeviceInfo.SerialNumber</code></td>
</tr>
<tr class="odd">
<td style="text-align: right;">DeviceProductClass</td>
<td style="text-align: center;"><code>6</code></td>
<td style="text-align: center;"><code>16</code></td>
<td
style="text-align: left;"><code>Device.DeviceInfo.ProductClass</code></td>
</tr>
</tbody>
</table>
<p>These Encapsulated Options are carried in DHCPv4 V-I Vendor Class
Option (option 125) or DHCPv6 V-I Vendor Class Option (option 17) with
an element identified with the IANA Enterprise Number for the Broadband
Forum that follows the format defined below. The IANA Enterprise Number
for the Broadband Forum is 3561 in decimal (the ADSL Forum entry in the
IANA Private Enterprise Numbers registry).</p>
<p><strong><span id="r-dis.2c"
class="auto-hoverlink">R-DIS.2c</span></strong> - When an Agent receives
a DHCPv4 response (DHCPOFFER or DHCPACK) or a DHCPv6 response (ADVERTISE
or REPLY) with this information, it MUST populate the
<code>Device.GatewayInfo</code> Object as defined in the Device:2 Data
Model <span class="citation" data-cites="TR-181"><a href="#ref-TR-181"
role="doc-biblioref">[3]</a></span>. Specifically, it MUST set the the
parameters <code>ManufacturerOUI</code>, <code>ProductClass</code> and
<code>SerialNumber</code>, if present and
<code>ManagementProtocol</code> MUST be set to “CWMP”. If any of the
parameters are not present then they MUST be set to an empty string. If
the DHCP release expires, or the USP Endpoint doesnt recieve this
information, the Parameters in the <code>Device.GatewayInfo</code>
Object MUST be set to an empty strings.</p>
<p><strong><span id="r-dis.2d"
class="auto-hoverlink">R-DIS.2d</span></strong> - When an Agent performs
mDNS discovery (see <a href="#sec:discovery" class="heading">Discovery
and Advertisement</a>) and recieves a PTR record (see <a
href="#sec:dns-sd-records" class="heading">DNS-SD Records</a>) that
match the same IP address as the DHCP response from (<a href="#r-dis.2c"
class="requirement">R-DIS.2c</a>), it MUST also set the
<code>Device.GatewayInfo.ManagementProtocol</code> Parameter to “USP”,
and <code>Device.GatewayInfo.EndpointID</code> Parameter to the USP
EndpointID received in the PTR record.</p>
<h2 class="auto-hoverlink" data-info="header" id="sec:using-mdns">3.5
Using mDNS</h2>
<p><strong><span id="r-dis.3"
class="auto-hoverlink">R-DIS.3</span></strong> - If mDNS discovery is
supported by a USP Endpoint, the USP Endpoint MUST implement mDNS client
and server functionality as defined in RFC 6762 <span class="citation"
data-cites="RFC6762"><a href="#ref-RFC6762"
role="doc-biblioref">[20]</a></span>.</p>
<p><strong><span id="r-dis.4"
class="auto-hoverlink">R-DIS.4</span></strong> - If mDNS advertisement
for a MTP is enabled on an Endpoint, the Endpoint MUST listen for
messages using that MTP from other Endpoints requesting establishment of
USP communication over that MTP.</p>
<p><strong><span id="r-dis.5"
class="auto-hoverlink">R-DIS.5</span></strong> - If mDNS is enabled, a
USP Endpoint MUST use mDNS to resolve a FQDN with domain
“<code>.local.</code>”.</p>
<p>In general, the expectation is that Agents will advertise themselves
so they will be discoverable by Controllers. Controllers are not
expected to advertise themselves, but are expected to discover Agents
and respond to applicable mDNS requests from Agents. Agents will use
mDNS to resolve a Controller “<code>.local.</code>” FQDN (and get DNS-SD
records) when the Agent needs to send a Notification to that
Controller.</p>
<h2 class="auto-hoverlink" data-info="header" id="sec:using-dns">3.6
Using DNS</h2>
<p>Requirements for implementation of a DNS client and configuration of
the DNS client with DNS server address(es) (through static
configuration, DHCPv4, DHCPv6, or Router Solicitation) are not provided.
These are sufficiently well-known that they were not considered
necessary for this specification. If the Agent knows of no DNS Server,
it cannot do DNS resolution.</p>
<p><strong><span id="r-dis.6"
class="auto-hoverlink">R-DIS.6</span></strong> - If DNS is enabled, an
Endpoint MUST use DNS to request IP address(es) (A and/or AAAA records,
depending on confiured IP stacks) for a FQDN with domain other than ones
used for mDNS (<a href="#r-dis.5" class="requirement">R-DIS.5</a>).</p>
<p>If the Endpoint is programmatically set to request other resource
records, it will request those, too.</p>
<p><strong><span id="r-dis.7"
class="auto-hoverlink">R-DIS.7</span></strong> - If the Agent is
resolving an FQDN for a Controller, and the MTP or resource path are
unknown, the Agent MUST request DNS-SD information (PTR, SRV and TXT
resource records) in addition to A, AAAA or other resource records it is
programmatically set to request.</p>
<h2 class="auto-hoverlink" data-info="header"
id="sec:dns-sd-records">3.7 DNS-SD Records</h2>
<p>DNS Service Discovery (DNS-SD) RFC 6763 <span class="citation"
data-cites="RFC6763"><a href="#ref-RFC6763"
role="doc-biblioref">[21]</a></span> is a mechanism for naming and
structuring DNS resource records to facilitate service discovery. It can
be used to create DNS records for USP Endpoints, so they can be
discoverable via DNS PTR queries RFC 1035 <span class="citation"
data-cites="RFC1035"><a href="#ref-RFC1035"
role="doc-biblioref">[8]</a></span> or Multicast DNS (mDNS) RFC 6762
<span class="citation" data-cites="RFC6762"><a href="#ref-RFC6762"
role="doc-biblioref">[20]</a></span>. DNS-SD uses DNS SRV and TXT
records to express information about “services”, and DNS PTR records to
help locate the SRV and TXT records. To discover these DNS records, DNS
or mDNS queries can be used. RFC 6762 <span class="citation"
data-cites="RFC6762"><a href="#ref-RFC6762"
role="doc-biblioref">[20]</a></span> recommends using the query type PTR
to get both the SRV and TXT records. A and AAAA records will also be
returned, for address resolution.</p>
<p>The format of a DNS-SD Service Instance Name (which is the resource
record (RR) Name of the DNS SRV and TXT records) is
“<code>&lt;Instance&gt;.&lt;Service&gt;.&lt;Domain&gt;</code>”.
<code>&lt;Instance&gt;</code> will be the USP Endpoint Identifier of the
USP Endpoint.</p>
<p><strong><span id="r-dis.8"
class="auto-hoverlink">R-DIS.8</span></strong> - USP Endpoint DNS-SD
records MUST include the USP Endpoint Identifier of the USP Endpoint as
the DNS-SD Service Instance Name.</p>
<p>Service Name values <a
href="http://www.broadband-forum.org/assignments">registered by BBF with
IANA</a> used by USP are shown below. As described in RFC 6763 <span
class="citation" data-cites="RFC6763"><a href="#ref-RFC6763"
role="doc-biblioref">[21]</a></span>, the <code>&lt;Service&gt;</code>
part of a Service Instance Name is constructed from these values as
“<code>_&lt;Service Name&gt;._&lt;Transport Protocol&gt;</code>” (e.g.,
“<code>_usp-agt-ws._tcp</code>”).</p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:iana-registered-usp-service-names">3.7.1 IANA-Registered USP
Service Names</h3>
<table>
<thead>
<tr class="header">
<th style="text-align: right;">Service Name</th>
<th style="text-align: center;">Transport Protocol</th>
<th style="text-align: center;">MTP</th>
<th style="text-align: left;">Type of USP Endpoint</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: right;"><code>usp-agt-coap</code></td>
<td style="text-align: center;">udp</td>
<td style="text-align: center;">CoAP</td>
<td style="text-align: left;">Agent</td>
</tr>
<tr class="even">
<td style="text-align: right;"><code>usp-agt-mqtt</code></td>
<td style="text-align: center;">tcp</td>
<td style="text-align: center;">MQTT</td>
<td style="text-align: left;">Agent</td>
</tr>
<tr class="odd">
<td style="text-align: right;"><code>usp-agt-stomp</code></td>
<td style="text-align: center;">tcp</td>
<td style="text-align: center;">STOMP</td>
<td style="text-align: left;">Agent</td>
</tr>
<tr class="even">
<td style="text-align: right;"><code>usp-agt-ws</code></td>
<td style="text-align: center;">tcp</td>
<td style="text-align: center;">WebSocket</td>
<td style="text-align: left;">Agent</td>
</tr>
<tr class="odd">
<td style="text-align: right;"><code>usp-ctr-coap</code></td>
<td style="text-align: center;">udp</td>
<td style="text-align: center;">CoAP</td>
<td style="text-align: left;">Controller</td>
</tr>
<tr class="even">
<td style="text-align: right;"><code>usp-ctr-mqtt</code></td>
<td style="text-align: center;">tcp</td>
<td style="text-align: center;">MQTT</td>
<td style="text-align: left;">Controller</td>
</tr>
<tr class="odd">
<td style="text-align: right;"><code>usp-ctr-stomp</code></td>
<td style="text-align: center;">tcp</td>
<td style="text-align: center;">STOMP</td>
<td style="text-align: left;">Controller</td>
</tr>
<tr class="even">
<td style="text-align: right;"><code>usp-ctr-ws</code></td>
<td style="text-align: center;">tcp</td>
<td style="text-align: center;">WebSocket</td>
<td style="text-align: left;">Controller</td>
</tr>
</tbody>
</table>
<!--
| `usp-agt-http` | tcp | HTTP | Agent |
| `usp-ctr-http` | tcp | HTTP | Controller |
-->
<p>DNS PTR records with a service subtype identifier (e.g.,
<code>._&lt;subtype&gt;._usp-agt-ws._tcp.&lt;Domain&gt;</code>) in the
RR can be used to provide searchable simple (single layer) functional
groupings of USP Agents. The registry of subtypes for Service Names
registered by BBF is listed at <a
href="http://www.broadband-forum.org/assignments">www.broadband-forum.org/assignments</a>.
DNS SRV and TXT records can be pointed to by multiple PTR records, which
allow a USP Endpoint to potentially be discoverable as belonging to
various functional groupings.</p>
<p>DNS TXT records allow for a small set of additional information to be
included in the reply sent to the querier. This information cannot be
used as search criteria. The registry of TXT record attributes for BBF
Service Names are listed at <a
href="http://www.broadband-forum.org/assignments">www.broadband-forum.org/assignments</a>.</p>
<p><strong><span id="r-dis.9"
class="auto-hoverlink">R-DIS.9</span></strong> - Agent DNS-SD records
MUST include a TXT record with the “path” and “name” attributes.</p>
<p><strong><span id="r-dis.10"
class="auto-hoverlink">R-DIS.10</span></strong> - The “name” attribute
included in the Agent DNS-SD records MUST be identical to the
<code>FriendlyName</code> Parameter defined in the Device:2 Data Model
<span class="citation" data-cites="TR-181"><a href="#ref-TR-181"
role="doc-biblioref">[3]</a></span>, if the <code>FriendlyName</code>
Parameter is implemented.</p>
<p><strong><span id="r-dis.11"
class="auto-hoverlink">R-DIS.11</span></strong> - Controller DNS-SD
records MUST include a TXT record with the “path” attribute.</p>
<p>The “path” attribute is dependent on each <a href="#sec:mtp"
class="heading">MTP</a>.</p>
<p><strong><span id="r-dis.11a"
class="auto-hoverlink">R-DIS.11a</span></strong> - If a USP Endpoint
requires MTP encryption to be used when connecting to its advertised
service, it MUST include the “encrypt” parameter in the TXT record.</p>
<p>The “encrypt” parameter is Boolean and does not require a value to be
specified. Its presence means MTP encryption is required when connecting
to the advertised service. Its absence means MTP encryption is not
required when connecting to the advertised service.</p>
<p>The TXT record can include other attributes defined in the TXT record
attribute registry, as well.</p>
<p>Whether a particular USP Endpoint responds to DNS or mDNS queries or
populates (through configuration or mDNS advertisement) their
information in a local DNS-SD server can be a configured option that can
be enabled/disabled, depending on the intended deployment usage
scenario.</p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:example-controller-unicast-dns-sd-resource-records">3.7.2
Example Controller Unicast DNS-SD Resource Records</h3>
<pre><code>    ; One PTR record for each supported MTP
    _usp-ctr-ws._tcp.host.example.com      PTR &lt;USP ID&gt;._usp-ctr-ws._tcp.example.com.

    ; One SRV+TXT (DNS-SD Service Instance) record for each supported MTP
    &lt;USP ID&gt;._usp-ctr-ws._tcp.example.com.   SRV 0 1 5684 host.example.com.
    &lt;USP ID&gt;._usp-ctr-ws._tcp.example.com.   TXT &quot;&lt;length byte&gt;path=&lt;pathname&gt;&lt;length byte&gt;encrypt&quot;

    ; Controller A and AAAA records
    host.example.com.  A      192.0.2.200
    host.example.com.  AAAA   2001:db8::200</code></pre>
<h3 class="auto-hoverlink" data-info="header"
id="sec:example-agent-multicast-dns-sd-resource-records">3.7.3 Example
Agent Multicast DNS-SD Resource Records</h3>
<pre><code>    ; One PTR record (DNS-SD Service) for each supported MTP
    _usp-agt-ws._tcp                 PTR &lt;USP ID&gt;._usp-agt-ws._tcp.local.

    ; One PTR record (DNS-SD Service Subtype) for each supported MTP per device type
    _iot-device._sub._usp-agt-ws._tcp    PTR &lt;USP ID&gt;._usp-agt-ws._tcp.local.
    _gateway._sub._usp-agt-ws._tcp       PTR &lt;USP ID&gt;._usp-agt-ws._tcp.local.

    ; One SRV+TXT record (DNS-SD Service Instance) for each supported MTP
    &lt;USP ID&gt;._usp-agt-ws._tcp.local.    SRV 0 1 5684 &lt;USP ID&gt;.local.
    &lt;USP ID&gt;._usp-agt-ws._tcp.local.    TXT &quot;&lt;length byte&gt;path=&lt;pathname&gt;&lt;length byte&gt;name=kitchen light&lt;length byte&gt;encrypt&quot;

    ; Agent A and AAAA records
    &lt;USP ID&gt;.local.  A      192.0.2.100
    &lt;USP ID&gt;.local.  AAAA   2001:db8::100</code></pre>
<h3 class="auto-hoverlink" data-info="header"
id="sec:example-controller-multicast-dns-sd-resource-records">3.7.4
Example Controller Multicast DNS-SD Resource Records</h3>
<p>LAN Controllers do not need to have PTR records, as they will only be
queried using the DNS-SD instance identifier of the Controller.</p>
<pre><code>    ; One SRV+TXT record (DNS-SD Service Instance) for each supported MTP
    &lt;USP ID&gt;._usp-ctr-ws._tcp.local.    SRV 0 1 5683 &lt;USP ID&gt;.local.
    &lt;USP ID&gt;._usp-ctr-ws._tcp.local.    TXT &quot;&lt;length byte&gt;path=&lt;pathname&gt;&quot;

    ; Controller A and AAAA records
    &lt;USP ID&gt;.local.  A      192.0.2.200
    &lt;USP ID&gt;.local.  AAAA   2001:db8::200</code></pre>
<h2 class="auto-hoverlink" data-info="header"
id="sec:using-the-sendonboardrequest-operation-and-onboardrequest-notification">3.8
Using the SendOnBoardRequest() operation and OnBoardRequest
notification</h2>
<p>An “OnBoardRequest” notification can be sent by an Agent to a
Controller to begin an on-boarding process (for example, when the Agent
first comes online and discovers a Controller using DHCP). Its use is
largely driven by policy, but there is a mechanism other Controllers can
use to ask an Agent to send “OnBoardRequest” to another Controller: the
SendOnBoardRequest() command is defined in the Device:2 Data Model <span
class="citation" data-cites="TR-181"><a href="#ref-TR-181"
role="doc-biblioref">[3]</a></span>. See <a
href="#sec:notification-types" class="heading">Notification Types</a>
for additional information about the OnBoardRequest notification.</p>
<h1 class="auto-hoverlink" data-info="header" id="sec:mtp">4 Message
Transfer Protocols</h1>
<p>USP messages are sent between Endpoints over one or more Message
Transfer Protocols.</p>
<p><em>Note: Message Transfer Protocol was a term adopted to avoid
confusion with the term “Transport”, which is often overloaded to
include both application layer (e.g. WebSocket) and the actual OSI
Transport layer (e.g. TCP). Throughout this document, Message Transfer
Protocol (MTP) refers to application layer transport.</em></p>
<h2 class="auto-hoverlink" data-info="header"
id="sec:generic-requirements">4.1 Generic Requirements</h2>
<p>The requirements in this section are common to all MTPs.</p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:supporting-multiple-mtps">4.1.1 Supporting Multiple MTPs</h3>
<p>Agents and Controllers may support more than one MTP. When an Agent
supports multiple MTPs, the Agent may be configured with Parameters for
reaching a particular Controller across more than one MTP. When an Agent
needs to send a Notification to such a Controller, the Agent can be
designed (or possibly configured) to select a particular MTP, to try
sending the Notification to the Controller on all MTPs simultaneously,
or to try MTPs sequentially. USP has been designed to allow Endpoints to
recognize when they receive a duplicate Message and to discard any
duplicates. Endpoints will always send responses on the same MTP where
the Message was received.</p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:securing-mtps">4.1.2 Securing MTPs</h3>
<p>This specification places the following requirement for encrypting
MTP headers and payloads on USP implementations that are intended to be
used in environments where USP Messages will be transported across the
Internet:</p>
<p><strong><span id="r-mtp.0"
class="auto-hoverlink">R-MTP.0</span></strong> – The Message Transfer
Protocol MUST use secure transport when USP Messages cross inter-network
boundaries.</p>
<p>For example, it may not be necessary to use MTP layer security when
within an end-user’s local area network (LAN). It is necessary to secure
transport to and from the Internet, however. If the device implementer
can reasonably expect Messages to be transported across the Internet
when the device is deployed, then the implementer needs to ensure the
device supports encryption of all MTP protocols.</p>
<p>MTPs that operate over TCP will be expected to implement, at least,
TLS 1.2 as defined in <span class="citation" data-cites="RFC5246"><a
href="#ref-RFC5246" role="doc-biblioref">[33]</a></span>.</p>
<p>Specific requirements for implementing these are provided in the
individual MTP sections.</p>
<p><strong><span id="r-mtp.1"
class="auto-hoverlink">R-MTP.1</span></strong> – When TLS is used to
secure an MTP, an Agent MUST require the MTP peer to provide an X.509
certificate.</p>
<p><strong><span id="r-mtp.2"
class="auto-hoverlink">R-MTP.2</span></strong> - An Agent capable of
obtaining absolute time SHOULD wait until it has accurate absolute time
before establishing TLS encryption to secure MTP communication. If an
Agent for any reason is unable to obtain absolute time, it can establish
TLS without waiting for accurate absolute time. If an Agent chooses to
establish TLS before it has accurate absolute time (or if it does not
support absolute time), it MUST ignore those components of the received
X.509 certificate that involve absolute time, e.g. not-valid-before and
not-valid-after certificate restrictions.</p>
<p><strong><span id="r-mtp.3"
class="auto-hoverlink">R-MTP.3</span></strong> - An Agent that has
obtained an accurate absolute time MUST validate those components of the
received X.509 certificate that involve absolute time.</p>
<p><strong><span id="r-mtp.4"
class="auto-hoverlink">R-MTP.4</span></strong> - When an Agent receives
an X.509 certificate while establishing TLS encryption of the MTP, the
Agent MUST execute logic that achieves the same results as in the
mandatory decision flow elements (identified with “MUST”) from <a
href="#fig:receiving-a-x509-certificate" class="figure">Figure
2</a>.</p>
<p><strong><span id="r-mtp.4a"
class="auto-hoverlink">R-MTP.4a</span></strong> - When an Agent receives
an X.509 certificate while establishing TLS encryption of the MTP, the
Agent SHOULD execute logic that achieves the same results as in the
optional decision flow elements (identified with “OPT”) from <a
href="#fig:receiving-a-x509-certificate" class="figure">Figure
2</a>.</p>
<figure id="fig:receiving-a-x509-certificate">
<img src="mtp/validate-cert.png" id="img:receiving-a-x.509-certificate"
alt="Receiving a X.509 Certificate" />
<figcaption><div class="auto-hoverlink"
data-anchor="fig:receiving-a-x509-certificate">
Figure 2: Receiving a X.509 Certificate
</div></figcaption>
</figure>
<p><em>Note: The .local and .home.arpa domains are defined by the IETF
as “Special-Use Domains” for use inside any LAN. It is not possible for
an external Certificate Authority (CA) to vouch for whether a LAN device
“owns” a particular name in one of these domains (inside a particular
LAN) and these LAN networks have no internal CA. Therefore, it is not
possible to validate FQDNs within these domains. The Internet Assigned
Numbers Authority (IANA) maintains a registry of <a
href="https://www.iana.org/assignments/special-use-domain-names/special-use-domain-names.xhtml">Special
Use Domains</a>.</em></p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:usp-record-encapsulation">4.1.3 USP Record Encapsulation</h3>
<p>The USP Record is defined as the Message Transfer Protocol (MTP)
payload, encapsulating a sequence of datagrams that comprise the USP
Message as well as providing additional metadata needed for integrity
protection, payload protection and delivery of fragmented USP Messages.
Additional metadata fields are used to identify the E2E session context,
determine the state of the segmentation and reassembly function,
acknowledge received datagrams, request retransmissions, and determine
the type of encoding and security mechanism used to encode the USP
Message.</p>
<p>When not explicitly set or included in a USP Record or USP Message,
the fields have a default value based on the type of field:</p>
<ul>
<li>For strings, the default value is the empty string.</li>
<li>For bytes, the default value is empty bytes.</li>
<li>For bools, the default value is <code>false</code>.</li>
<li>For numeric types, the default value is zero.</li>
<li>For enums, the default value is the first defined enum value, which
must be 0.</li>
<li>For a <code>oneof</code> field, none of the allowed values are
assumed if the field is absent.</li>
<li><code>repeated</code> fields can be included any number of times,
including zero.</li>
</ul>
<p>If there is no requirement stating a field must be present, it is not
necessary to include the field in a sent Record or Message. The
receiving Endpoint will use default values for fields not included in a
received Record or Message.</p>
<p><strong><span id="r-mtp.4b"
class="auto-hoverlink">R-MTP.4b</span></strong> - Any field that is
noted as “Required” in its description MUST be sent.</p>
<p>A Record or Message without a required field will fail to be
processed by a receiving Endpoint. For additional information, default
values (when fields are missing) are described in the “Default Values”
section of Protocol Buffers <span class="citation"
data-cites="PROTOBUF"><a href="#ref-PROTOBUF"
role="doc-biblioref">[4]</a></span>.</p>
<h4 class="auto-hoverlink" data-info="header"
id="sec:record-definition">4.1.3.1 Record Definition</h4>
<p><em>Note: This version of the specification defines the USP Record in
<a href="#sec:encoding" class="heading">Protocol Buffers v3</a>. This
part of the specification may change to a more generic description
(normative and non-normative) if further encodings are specified in
future versions.</em></p>
<p><code>string version</code></p>
<p>Required. Version (Major.Minor) of the USP Protocol (e.g.,
“1.3”).</p>
<p><em>Note: The version field is used for USP Endpoints to set
expectations about their behavior for other USP Endpoints.</em>
<strong><em>A USP Endpoint that receives a Record indicating a version
higher than it supports can expect to receive messages it may not
understand or encounter other unexpected behavior.</em></strong> <em>USP
Endpoints are expected to handle these inconsistencies gracefully (For
example, using the 7001 Message Not Supported Error).</em></p>
<p><code>string to_id</code></p>
<p>Required. Receiving/Target USP Endpoint Identifier.</p>
<p><code>string from_id</code></p>
<p>Required. Originating/Source USP Endpoint Identifier.</p>
<p><code>enum PayloadSecurity payload_security</code></p>
<p>Optional. An enumeration of type PayloadSecurity. When the payload is
present, this indicates the protocol or mechanism used to secure the
payload (if any) of the USP Message. The value of <code>TLS12</code>
means TLS 1.2 or later (with backward compatibility to TLS 1.2) will be
used to secure the payload (see <a href="#sec:tls-payload-encapsulation"
class="heading">TLS Payload Encapsulation</a> for more information).</p>
<p>Valid values are:</p>
<pre><code>PLAINTEXT (0)
TLS12 (1)</code></pre>
<p><code>bytes mac_signature</code></p>
<p>Optional. When integrity protection of non-payload fields is
performed, this is the message authentication code or signature used to
ensure the integrity of the non-payload fields of the USP Record.</p>
<p><code>bytes sender_cert</code></p>
<p>Optional. The PEM encoded certificate, or certificate chain, of the
sending USP Endpoint used to provide the signature in the
<code>mac_signature</code> field, when integrity protection is used and
the payload security mechanism doesn’t provide the mechanism to generate
the <code>mac_signature</code>.</p>
<p><code>oneof record_type</code></p>
<p>Required. This field contains one of the types given below:</p>
<p><code>NoSessionContextRecord no_session_context</code></p>
<p><code>SessionContextRecord session_context</code></p>
<p><code>WebSocketConnectRecord websocket_connect</code></p>
<p><code>MQTTConnectRecord mqtt_connect</code></p>
<p><code>STOMPConnectRecord stomp_connect</code></p>
<p><code>UDSConnectRecord uds_connect</code></p>
<p><code>DisconnectRecord disconnect</code></p>
<h5 class="auto-hoverlink" data-info="header"
id="sec:nosessioncontextrecord-fields">4.1.3.1.1 NoSessionContextRecord
fields</h5>
<p>The following describe the fields included if
<code>record_type</code> is <code>no_session_context</code>.</p>
<p><code>bytes payload</code></p>
<p>Required. The USP Message.</p>
<h5 class="auto-hoverlink" data-info="header"
id="sec:sessioncontextrecord-fields">4.1.3.1.2 SessionContextRecord
fields</h5>
<p>The following describe the fields included if
<code>record_type</code> is <code>session_context</code>.</p>
<p><code>uint64 session_id</code></p>
<p>Required. This field is the Session Context identifier.</p>
<p><code>uint64 sequence_id</code></p>
<p>Required. Datagram sequence identifier. Used only for exchange of USP
Records with an E2E Session Context. The field is initialized to 1 when
starting a new Session Context and incremented after each sent USP
Record.</p>
<p><em>Note: Endpoints maintain independent values for received and sent
sequence_id for a Session Context, based respectively on the number of
received and sent Records.</em></p>
<p><code>uint64 expected_id</code></p>
<p>Required. This field contains the next <code>sequence_id</code> the
sender is expecting to receive, which implicitly acknowledges to the
recipient all transmitted datagrams less than <code>expected_id</code>.
Used only for exchange of USP Records with an E2E Session Context.</p>
<p><code>uint64 retransmit_id</code></p>
<p>Optional. Used to request a USP Record retransmission by a USP
Endpoint to request a missing USP Record using the missing USP Record’s
anticipated <code>sequence_id</code>. Used only for exchange of USP
Records with an E2E Session Context. Will be received as <code>0</code>
when no retransmission is requested.</p>
<p><code>enum PayloadSARState payload_sar_state</code></p>
<p>Optional. An enumeration of type PayloadSARState. When payload is
present, indicates the segmentation and reassembly state represented by
the USP Record. Valid values are:</p>
<pre><code>NONE (0)
BEGIN (1)
INPROCESS (2)
COMPLETE (3)</code></pre>
<p><code>enum PayloadSARState payloadrec_sar_state</code></p>
<p>Optional. An enumeration of type PayloadSARState. When payload
segmentation is being performed, indicates the segmentation and
reassembly state represented by an instance of the payload datagram. If
<code>payload_sar_state</code> = <code>0</code> (or is not included or
not set), then <code>payloadrec_sar_state</code> will be <code>0</code>
(or not included or not set). Valid values are:</p>
<pre><code>NONE (0)
BEGIN (1)
INPROCESS (2)
COMPLETE (3)</code></pre>
<p><code>repeated bytes payload</code></p>
<p>Optional. This repeated field is a sequence of zero, one, or multiple
datagrams. It contains the Message, in either <code>PLAINTEXT</code> or
encrypted format. When using <code>TLS12</code> payload security, this
contains the encrypted TLS records, either sequentially in a single
<code>payload</code> field, or divided into multiple
<code>payload</code> fields. When using <code>PLAINTEXT</code> payload
security there will be a single <code>payload</code> field for any
Message being sent.</p>
<h5 class="auto-hoverlink" data-info="header"
id="sec:websocketconnectrecord-fields">4.1.3.1.3 WebSocketConnectRecord
fields</h5>
<p>This Record type has no fields.</p>
<h5 class="auto-hoverlink" data-info="header"
id="sec:mqttconnectrecord-fields">4.1.3.1.4 MQTTConnectRecord
fields</h5>
<p>The following describe the fields included if
<code>record_type</code> is <code>mqtt_connect</code>.</p>
<p><code>enum MQTTVersion version</code></p>
<p>Required. The MQTT protocol version used by the USP Endpoint to send
this Record. Valid values are:</p>
<pre><code>V3_1_1 (0)
V5 (1)</code></pre>
<p><code>string subscribed_topic</code></p>
<p>Required. A MQTT Topic where the USP Endpoint sending this Record can
be reached (i.e. a non-wildcarded MQTT Topic it is subscribed to).</p>
<h5 class="auto-hoverlink" data-info="header"
id="sec:stompconnectrecord-fields">4.1.3.1.5 STOMPConnectRecord
fields</h5>
<p>The following describe the fields included if
<code>record_type</code> is <code>stomp_connect</code>.</p>
<p><code>enum STOMPVersion version</code></p>
<p>Required. The STOMP protocol version used by the USP Endpoint to send
this Record. Valid values are:</p>
<pre><code>V1_2 (0)</code></pre>
<p><code>string subscribed_destination</code></p>
<p>Required. A STOMP Destination where the USP Endpoint sending this
Record can be reached (i.e. a STOMP Destination it is subscribed
to).</p>
<h5 class="auto-hoverlink" data-info="header"
id="sec:udsconnectrecord-fields">4.1.3.1.6 UDSConnectRecord fields</h5>
<p>This Record type has no fields.</p>
<h5 class="auto-hoverlink" data-info="header"
id="sec:disconnectrecord-fields">4.1.3.1.7 DisconnectRecord fields</h5>
<p>The following describe the fields included if
<code>record_type</code> is <code>disconnect</code>.</p>
<p><code>fixed32 reason_code</code></p>
<p>Optional. A code identifying the reason of the disconnect.</p>
<p><code>string reason</code></p>
<p>Optional. A string describing the reason of the disconnect.</p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:usp-record-errors">4.1.4 USP Record Errors</h3>
<p>A variety of errors can occur while establishing and during a USP
communication flow. In order to signal such problems to the other
Endpoint while processing an incoming E2E Session Context Record or a
Record containing a Message of the type Request, an Endpoint
encountering such a problem can create a USP Record containing a Message
of type Error and transmit it over the same MTP and connection which was
used when the error was encountered.</p>
<p>For this mechanism to work and to prevent information leakage, the
sender causing the problem needs to be able to create a valid USP Record
containing a valid source Endpoint ID and a correct destination Endpoint
ID. In addition a MTP specific return path needs to be known so the
error can be delivered.</p>
<p><strong><span id="r-mtp.5"
class="auto-hoverlink">R-MTP.5</span></strong> - A recipient of an
erroneous USP Record MUST create a Record with a Message of type Error
and deliver it to sender if the source Endpoint ID is valid, the
destination Endpoint ID is its own, the Record contains a USP Message of
type Request, the Message ID can be extracted, and a MTP-specific return
path is known. If any of those criteria on the erroneous Record are not
met, it MUST be ignored.</p>
<p>The following error codes (in the range 7100-7199) are defined to
allow the Error to be more specifically indicated. Additional
requirements for these error codes are included in the specific MTP
definition, where appropriate.</p>
<table>
<colgroup>
<col style="width: 14%" />
<col style="width: 30%" />
<col style="width: 54%" />
</colgroup>
<thead>
<tr class="header">
<th style="text-align: left;">Code</th>
<th style="text-align: left;">Name</th>
<th style="text-align: left;">Description</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;"><code>7100</code></td>
<td style="text-align: left;">Record could not be parsed</td>
<td style="text-align: left;">This error indicates the received USP
Record could not be parsed.</td>
</tr>
<tr class="even">
<td style="text-align: left;"><code>7101</code></td>
<td style="text-align: left;">Secure session required</td>
<td style="text-align: left;">This error indicates USP layer <a
href="#sec:secure-message-exchange" class="heading">Secure Message
Exchange</a> is required.</td>
</tr>
<tr class="odd">
<td style="text-align: left;"><code>7102</code></td>
<td style="text-align: left;">Secure session not supported</td>
<td style="text-align: left;">This error indicates USP layer <a
href="#sec:secure-message-exchange" class="heading">Secure Message
Exchange</a> was indicated in the received Record but is not supported
by the receiving Endpoint.</td>
</tr>
<tr class="even">
<td style="text-align: left;"><code>7103</code></td>
<td style="text-align: left;">Segmentation and reassembly not
supported</td>
<td style="text-align: left;">This error indicates segmentation and
reassembly was indicated in the received Record but is not supported by
the receiving Endpoint.</td>
</tr>
<tr class="odd">
<td style="text-align: left;"><code>7104</code></td>
<td style="text-align: left;">Invalid Record value</td>
<td style="text-align: left;">This error indicates the value of at least
one Record field was invalid.</td>
</tr>
<tr class="even">
<td style="text-align: left;"><code>7105</code></td>
<td style="text-align: left;">Session Context terminated</td>
<td style="text-align: left;">This error indicates an existing Session
Context <a href="#sec:establishing-an-e2e-session-context"
class="heading">Establishing an E2E Session Context</a> is being
terminated.</td>
</tr>
<tr class="odd">
<td style="text-align: left;"><code>7106</code></td>
<td style="text-align: left;">Session Context not allowed</td>
<td style="text-align: left;">This error indicates use of Session
Context <a href="#sec:establishing-an-e2e-session-context"
class="heading">Establishing an E2E Session Context</a> is not allowed
or not supported.</td>
</tr>
</tbody>
</table>
<h3 class="auto-hoverlink" data-info="header"
id="sec:connect-and-disconnect-record-types">4.1.5 Connect and
Disconnect Record Types</h3>
<p>A Connect Record is a subgroup of Record types
(<code>record_type</code>), there is one Record type per USP MTP in this
subgroup. These Records are used to assert the USP Agent presence and
exchange needed information for proper start of communication between
Agent and Controller, the presence information is specifically useful
when using brokered MTPs.</p>
<p><strong><span id="r-mtp.6"
class="auto-hoverlink">R-MTP.6</span></strong> - If a USP Agent has the
necessary information to create a Connect Record, it MUST send the
associated Connect Record, specific for the MTP in use, after it has
successfully established an MTP communications channel to a USP
Controller.</p>
<p>The <code>DisconnectRecord</code> is a Record type used by a USP
Agent to indicate it wishes to end an on-going communication with a USP
Controller. It can be used for presence information, for sending
supplemental information about the disconnect event and to force the
remote USP Endpoint to purge some cached information about the current
session.</p>
<p><strong><span id="r-mtp.7"
class="auto-hoverlink">R-MTP.7</span></strong> - The USP Agent SHOULD
send a <code>DisconnectRecord</code> to the USP Controller before
disconnecting from an MTP communications channel. Upon receiving a
<code>DisconnectRecord</code>, a USP Controller MUST clear all cached
information relative to an existing E2E Session Context with that
Endpoint, including the information that a previous E2E Session Context
was established.</p>
<p>It is not mandatory for a USP Endpoint to close its MTP connection
after sending or receiving a <code>DisconnectRecord</code>.</p>
<p><strong><span id="r-mtp.8"
class="auto-hoverlink">R-MTP.8</span></strong> - After sending or
receiving a <code>DisconnectRecord</code> and maintaining the underlying
MTP communications channel or after establishing a new MTP
communications channel, the USP Endpoint MUST send or receive the
correct Connect Record type before exchanging any other USP Records.</p>
<p><strong><span id="r-mtp.9"
class="auto-hoverlink">R-MTP.9</span></strong> - A
<code>DisconnectRecord</code> SHOULD include the
<code>reason_code</code> and <code>reason</code> fields with an
applicable code from <a href="#sec:usp-record-errors"
class="heading">USP Record Errors</a>.</p>
<h2 class="auto-hoverlink" data-info="header"
id="sec:coap-binding-obsoleted">4.2 CoAP Binding (OBSOLETED)</h2>
<p><em>Note: The CoAP MTP was deprecated in USP 1.2. Due to the way it
is specified this MTP can only be used in local area networks under
narrow conditions. Please see <a href="#sec:websocket"
class="heading">Section 4.3</a> for a suitable alternative.</em></p>
<p><em>Note: The CoAP MTP was obsoleted in USP 1.3 as a natural
progression from being deprecated in USP 1.2.</em></p>
<p>The Constrained Application Protocol (CoAP) MTP transfers USP Records
between USP Endpoints using the CoAP protocol as defined in RFC 7252
<span class="citation" data-cites="RFC7252"><a href="#ref-RFC7252"
role="doc-biblioref">[36]</a></span>. Messages that are transferred
between CoAP clients and servers utilize a request/response messaging
interaction based on RESTful architectural principles. The following
figure depicts the transfer of the USP Records between USP
Endpoints.</p>
<figure id="fig:usp-request-response-over-coap">
<img src="mtp/coap/usp-request-response-over-coap.png"
id="img:example-usp-requestresponse-over-the-coap-mtp"
alt="Example: USP Request/Response over the CoAP MTP" />
<figcaption><div class="auto-hoverlink"
data-anchor="fig:usp-request-response-over-coap">
Figure 3: Example: USP Request/Response over the CoAP MTP
</div></figcaption>
</figure>
<p>In this example, a USP Request is encoded within a USP Record and
encapsulated within a CoAP request message. When a USP Endpoint receives
the CoAP request message the USP Endpoint immediately sends a CoAP
response message (with no USP Record) to indicate receipt of the
message. A USP Response encoded within a USP Record is encapsulated in a
new CoAP request message. When the USP Endpoint receives the USP
Response, it sends a CoAP response message that indicates receipt of the
message. Therefore, all Endpoints supporting CoAP will implement both
CoAP client and server.</p>
<p>As noted in the definition of a USP Request, this USP Record either
requests the Agent perform some action (create, update, delete, operate,
etc.), requests information about an Agent or one or more Service
Elements, or acts as a means to deliver Notifications from the Agent to
the Controller. Notifications will only cause a USP Response to be
generated if specified in the Notification Request. However, the CoAP
response will always be sent.</p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:mapping-usp-endpoints-to-coap-uris">4.2.1 Mapping USP Endpoints
to CoAP URIs</h3>
<p>Section 6 of RFC 7262 <span class="citation" data-cites="RFC7252"><a
href="#ref-RFC7252" role="doc-biblioref">[36]</a></span> discusses the
URI schemes for identifying CoAP resources and provides a means of
locating the resource. These resources are organized hierarchically and
governed by a CoAP server listening for CoAP requests on a given port.
USP Endpoints are one type of CoAP resource that is identified and
discovered.</p>
<p><strong><span id="r-coap.0"
class="auto-hoverlink">R-COAP.0</span></strong> - As the USP Endpoint is
a resource governed by a CoAP server, the CoAP server MUST also be
identified as defined in section 6 of RFC 7262 <span class="citation"
data-cites="RFC7252"><a href="#ref-RFC7252"
role="doc-biblioref">[36]</a></span>.</p>
<p><strong><span id="r-coap.1"
class="auto-hoverlink">R-COAP.1</span></strong> - A USP Endpoint MUST be
represented as a CoAP resource with the following resource
attributes:</p>
<ul>
<li>Identifier within the CoAP server (uri-path)</li>
<li>Resource type (rt): “<code>bbf.usp.endpoint</code>”</li>
<li>Interface (if): “<code>bbf.usp.c</code>” for USP Controller or
“<code>bbf.usp.a</code>” for USP Agent</li>
</ul>
<p>The identifier within the CoAP server is used to deliver messages to
the USP Endpoint. When this identifier is used to deliver messages to
the USP Endpoint, this identifier is a uri-path that represents the USP
Endpoint.</p>
<p><strong><span id="r-coap.2"
class="auto-hoverlink">R-COAP.2</span></strong> - A CoAP request message
MUST include a Uri-Query option that supplies the CoAP server URI of the
Endpoint that is the source of the CoAP request, formatted as
<code>?reply-to=&lt;coap or coaps uri&gt;</code>. The coap and coaps
URIs are defined in sections 6.1 and 6.2 of RFC 7262 <span
class="citation" data-cites="RFC7252"><a href="#ref-RFC7252"
role="doc-biblioref">[36]</a></span>. The URI MUST NOT include any
optional queries at the end.</p>
<p><strong><span id="r-coap.2a"
class="auto-hoverlink">R-COAP.2a</span></strong> - When a USP Endpoint
receives a CoAP request message it MUST use the reply-to Uri-Query
option included in the CoAP request as the CoAP URI for the USP Response
(if a response is required by the incoming USP Request).</p>
<p><strong><span id="r-coap.3"
class="auto-hoverlink">R-COAP.3</span></strong> - When creating DNS-SD
records (see <a href="#sec:dns-sd-records" class="heading">DNS-SD
Records</a>), an Endpoint MUST set the DNS-SD TXT record “path”
attribute equal to the value of the CoAP server identifier
(uri-path).</p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:mapping-usp-records-to-coap-messages">4.2.2 Mapping USP Records
to CoAP Messages</h3>
<p><strong><span id="r-coap.4"
class="auto-hoverlink">R-COAP.4</span></strong> - In order for USP
Records to be transferred between a USP Controller and Agent using CoAP,
the USP Record MUST be encapsulated within the CoAP message as defined
in RFC 7262 <span class="citation" data-cites="RFC7252"><a
href="#ref-RFC7252" role="doc-biblioref">[36]</a></span>.</p>
<p><strong><span id="r-coap.5"
class="auto-hoverlink">R-COAP.5</span></strong> – USP Records that
exceed the CoAP message size MUST be block encapsulated in accordance
with <span class="citation" data-cites="RFC7959"><a href="#ref-RFC7959"
role="doc-biblioref">[38]</a></span>.</p>
<p>USP Records are transferred using the CoAP resource that represents
the receiving USP Endpoint using the CoAP POST method as defined in RFC
7252.</p>
<p><strong><span id="r-coap.6"
class="auto-hoverlink">R-COAP.6</span></strong> - The CoAP
Content-Format for USP Records MUST be application/octet-stream (ID=42)
for <a href="#sec:encoding" class="heading">Message Encoding</a>.</p>
<p><strong><span id="r-coap.7"
class="auto-hoverlink">R-COAP.7</span></strong> - Upon successful
reception of the CoAP message using POST, the CoAP server MUST respond
with a response code of <code>2.04 (Changed)</code>.</p>
<h4 class="auto-hoverlink" data-info="header"
id="sec:handling-coap-request-failures">4.2.2.1 Handling CoAP Request
Failures</h4>
<p>At times CoAP requests fail to complete due to problems in the
underlying transport (e.g., timeout) or a failure response code received
from the CoAP server due to problems in the CoAP request sent by the
CoAP client (4.xx) or problems with the CoAP server implementation
(5.xx).</p>
<p><strong><span id="r-coap.8"
class="auto-hoverlink">R-COAP.8</span></strong> - CoAP clients and
servers MUST implement the required CoAP response codes defined in
section 5.9 of RFC 7262 <span class="citation" data-cites="RFC7252"><a
href="#ref-RFC7252" role="doc-biblioref">[36]</a></span>.</p>
<p><strong><span id="r-coap.9"
class="auto-hoverlink">R-COAP.9</span></strong> - When a CoAP client
receives a failure indication (e.g., timeout) from the underlying
transport layer, the CoAP client MUST indicate a timeout to the USP
Endpoint.</p>
<p><strong><span id="r-coap.10"
class="auto-hoverlink">R-COAP.10</span></strong> - When a CoAP client
receives a response code of 4.xx or 5.xx, the CoAP client MUST indicate
a CoAP failure to the USP Endpoint.</p>
<p>When a CoAP client sends a CoAP request, the CoAP client can provide
incorrect or missing information in the CoAP request. For example, a
CoAP client can send a CoAP request with an:</p>
<ul>
<li>Invalid CoAP method: The CoAP server responds with a
<code>4.05</code></li>
<li>Invalid Content-Format options: The CoAP server responds with a
<code>4.15</code></li>
<li>Invalid or not understandable payload: The CoAP server responds with
a <code>4.00</code></li>
</ul>
<p><strong><span id="r-coap.11"
class="auto-hoverlink">R-COAP.11</span></strong> - When a CoAP server
receives a CoAP request with an invalid CoAP method, the CoAP server
MUST respond with a <code>4.05</code> response code.</p>
<p><strong><span id="r-coap.12"
class="auto-hoverlink">R-COAP.12</span></strong> - When a CoAP server
receives a CoAP request with an invalid CoAP Content-Format option, the
CoAP server MUST respond with a <code>4.15</code> response code.</p>
<p><strong><span id="r-coap.13"
class="auto-hoverlink">R-COAP.13</span></strong> - When a CoAP server
receives a CoAP request and the receiving USP Endpoint cannot interpret
or decode the USP Record for processing, the CoAP server MUST respond
with a <code>4.00</code> response code.</p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:mtp-message-encryption">4.2.3 MTP Message Encryption</h3>
<p>CoAP MTP message encryption is provided using DTLS as described in
Section 9 of RFC 7262 <span class="citation" data-cites="RFC7252"><a
href="#ref-RFC7252" role="doc-biblioref">[36]</a></span>.</p>
<p>In section 9 of RFC 7262 <span class="citation"
data-cites="RFC7252"><a href="#ref-RFC7252"
role="doc-biblioref">[36]</a></span>, CoAP messages are secured using
one of three modes:</p>
<ul>
<li>NoSec: DTLS is disabled</li>
<li>PreSharedKey: DTLS is enabled and the MTP endpoint uses pre-shared
keys that are used to validate the identity of CoAP endpoints involved
in the message exchange</li>
<li>RawPublicKey: DTLS is enabled and the MTP endpoint has an asymmetric
key pair without a certificate. The MTP endpoint has an identity
calculated from the public key and a list of other MTP endpoints to
which it can communicate</li>
<li>Certificate: DTLS is enabled and the MTP endpoint has an asymmetric
key pair with an X.509 certificate.</li>
</ul>
<p><strong><span id="r-coap.14"
class="auto-hoverlink">R-COAP.14</span></strong> - CoAP clients and
servers MUST implement the NoSec and Certificate modes of CoAP security
as defined in RFC 7262 <span class="citation" data-cites="RFC7252"><a
href="#ref-RFC7252" role="doc-biblioref">[36]</a></span>.</p>
<p>While section 9 of RFC 7262 <span class="citation"
data-cites="RFC7252"><a href="#ref-RFC7252"
role="doc-biblioref">[36]</a></span> provides guidance on securing CoAP,
further guidance related to DTLS implementations for the Internet of
Things is provided by RFC 7925 <span class="citation"
data-cites="RFC7925"><a href="#ref-RFC7925"
role="doc-biblioref">[37]</a></span>.</p>
<p><strong><span id="r-coap.15"
class="auto-hoverlink">R-COAP.15</span></strong> - CoAP clients and
servers MUST implement the mandatory statements of RFC 7925 <span
class="citation" data-cites="RFC7925"><a href="#ref-RFC7925"
role="doc-biblioref">[37]</a></span> with the exception that:</p>
<ul>
<li>Section 4.4.1 USP Controller certificates can contain domain names
with wildcard characters per RFC 6125 <span class="citation"
data-cites="RFC6125"><a href="#ref-RFC6125"
role="doc-biblioref">[18]</a></span> guidance.</li>
<li>Section 4.4.2 Client certificate identifiers do not use EUI-64
identifier but instead use the identifier defined for Client
certificates in this Working Text.</li>
<li>Section 4.4.5 Client Certificate URLs are not required to be
implemented.</li>
</ul>
<p>As USP Endpoints play the role of both CoAP client and server; when
the MTP is secured using the Certificate mode of CoAP Security, the USP
Endpoint provides a X.509 certificate to the MTP peer.</p>
<p><strong><span id="r-coap.16"
class="auto-hoverlink">R-COAP.16</span></strong> – When the Certificate
mode of CoAP is used to secure an MTP, a USP Endpoint MUST provide an
X.509 certificate to the MTP peer.</p>
<p>Note that DTLS sessions established for an Endpoint’s CoAP client and
CoAP server are distinct. Therefore, it is possible for CoAP to be
encrypted in one direction and not the other. If this happens, the
requirements and flows in <a href="#sec:auth"
class="heading">Authentication and Authorization</a> will dictate that
<a href="#sec:secure-message-exchange" class="heading">Secure Message
Exchange</a> be used.</p>
<h2 class="auto-hoverlink" data-info="header" id="sec:websocket">4.3
WebSocket Binding</h2>
<p>The WebSockets MTP transfers USP Records between USP Endpoints using
the WebSocket protocol as defined in RFC 6455 <span class="citation"
data-cites="RFC6455"><a href="#ref-RFC6455"
role="doc-biblioref">[19]</a></span>. Messages that are transferred
between WebSocket clients and servers utilize a request/response
messaging interaction across an established WebSocket session.</p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:mapping-usp-endpoints-to-websocket-uris">4.3.1 Mapping USP
Endpoints to WebSocket URIs</h3>
<p>Section 3 of RFC 6455 discusses the URI schemes for identifying
WebSocket origin servers and their target resources. These resources are
organized hierarchically and governed by a WebSocket origin server
listening for WebSocket messages on a given port. USP Endpoints are one
type of WebSocket resource that is identified and discovered.</p>
<p><strong><span id="r-ws.1"
class="auto-hoverlink">R-WS.1</span></strong> - As the USP Endpoint is a
resource governed by a WebSocket origin server, the WebSocket server
MUST also be identified as defined in section 3 of RFC 6455 <span
class="citation" data-cites="RFC6455"><a href="#ref-RFC6455"
role="doc-biblioref">[19]</a></span>.</p>
<p><strong><span id="r-ws.2"
class="auto-hoverlink">R-WS.2</span></strong> - A USP Endpoint MUST be
represented as a WebSocket resource using the path component as defined
in section 3 of RFC 6455 <span class="citation" data-cites="RFC6455"><a
href="#ref-RFC6455" role="doc-biblioref">[19]</a></span>.</p>
<p><strong><span id="r-ws.3"
class="auto-hoverlink">R-WS.3</span></strong> - When creating DNS-SD
records (see <a href="#sec:discovery" class="heading">Discovery</a>), an
Endpoint MUST set the DNS-SD TXT record “path” attribute equal to the
value of the Websocket resource using the path component as defined in
section 3 of RFC 6455 <span class="citation" data-cites="RFC6455"><a
href="#ref-RFC6455" role="doc-biblioref">[19]</a></span>.</p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:handling-of-the-websocket-session">4.3.2 Handling of the
WebSocket Session</h3>
<p>When exchanging the USP Records across WebSockets MTPs, the two USP
Endpoints establish a WebSocket session. These WebSocket sessions are
expected to be long lived and are reused for subsequent USP Record
exchange. A WebSocket session is established using a handshake procedure
described in section 4 of RFC 6455. When a WebSocket connection is not
longer necessary, the WebSocket connection is closed according to
section 7 of RFC 6455. The following figure depicts a WebSocket session
handshake that is originated by an Agent.</p>
<figure id="fig:websocket-session-handshake">
<img src="mtp/websocket/websocket-session-handshake.png"
id="img:websocket-session-handshake"
alt="WebSocket Session Handshake" />
<figcaption><div class="auto-hoverlink"
data-anchor="fig:websocket-session-handshake">
Figure 4: WebSocket Session Handshake
</div></figcaption>
</figure>
<p>While WebSocket sessions can be established by either USP Controllers
or USP Agents in many deployment scenarios (e.g. communication between
USP Endpoints across the Internet), in general, USP Agents will
establish the WebSocket session and not expose an open port toward the
Internet for security reasons. Regardless of which entity establishes
the WebSocket session, at most one (1) open WebSocket session is
utilized between the USP Endpoints.</p>
<p><strong><span id="r-ws.4"
class="auto-hoverlink">R-WS.4</span></strong> - USP Endpoints that
exchange USP Records MUST utilize at most one (1) open WebSocket
session.</p>
<p><strong><span id="r-ws.5"
class="auto-hoverlink">R-WS.5</span></strong> - USP Agent MUST provide
the capability to originate the establishment of a WebSocket
session.</p>
<p><strong><span id="r-ws.6"
class="auto-hoverlink">R-WS.6</span></strong> - USP Agent MUST provide
the capability to accept the establishment of a WebSocket session from a
USP Controller.</p>
<p><em>Note: Requirement <a href="#r-ws.6"
class="requirement">R-WS.6</a> was altered from a MAY to a MUST in USP
1.2 to ensure that the WebSocket MTP is suitable for the in-home
communications use case.</em></p>
<p><strong><span id="r-ws.7"
class="auto-hoverlink">R-WS.7</span></strong> - A USP Endpoint MUST
implement the WebSocket handshake protocol to establish a WebSocket
connection as defined in section 4 of RFC 6455 <span class="citation"
data-cites="RFC6455"><a href="#ref-RFC6455"
role="doc-biblioref">[19]</a></span>.</p>
<p><strong><span id="r-ws.8"
class="auto-hoverlink">R-WS.8</span></strong> - A USP Endpoint MUST
implement the procedures to close a WebSocket connection as defined in
section 7 of RFC 6455 <span class="citation" data-cites="RFC6455"><a
href="#ref-RFC6455" role="doc-biblioref">[19]</a></span>.</p>
<h4 class="auto-hoverlink" data-info="header"
id="sec:mapping-usp-records-to-websocket-messages">4.3.2.1 Mapping USP
Records to WebSocket Messages</h4>
<p>During the establishment of the WebSocket session, the WebSocket
client informs the WebSocket server in the
<code>Sec-WebSocket-Protocol</code> header about the type of USP Records
that will be exchanged across the established WebSocket connection. For
USP Records, the <code>Sec-WebSocket-Protocol</code> header contains the
value <code>v1.usp</code>. When presented with a
<code>Sec-WebSocket-Protocol</code> header containing
<code>v1.usp</code>, the WebSocket Server serving a USP Endpoint returns
<code>v1.usp</code> in the response’s Sec-WebSocket-Protocol header. If
the WebSocket client doesn’t receive a
<code>Sec-WebSocket-Protocol</code> header with a value of
<code>v1.usp</code>, the WebSocket client does not establish the
WebSocket session.</p>
<p>When a WebSocket connection is being initiated with TLS, no USP
Record is sent until the TLS negotiation is complete. The WebSocket
server will be unable to identify the Endpoint ID of the client unless
it looks inside the certificate. To make it easier for the server to
identify the client, the request URI of the opening handshake contains a
<code>key=value</code> pair in its <code>query</code> component to
provide the Endpoint ID of the client. <code>eid</code> is used as the
key to the pair, while the value is the Endpoint ID of the client,
e.g. <code>eid=doc::agent</code>.</p>
<p><strong><span id="r-ws.9"
class="auto-hoverlink">R-WS.9</span></strong> - The WebSocket’s
handshake <code>Sec-WebSocket-Protocol</code> header for exchange of USP
Records using the protocol-buffers encoding mechanism MUST be
<code>v1.usp</code>.</p>
<p><strong><span id="r-ws.10"
class="auto-hoverlink">R-WS.10</span></strong> - A WebSocket client MUST
include the <code>Sec-WebSocket-Protocol</code> header for exchange of
USP Records when initiating a WebSocket session.</p>
<p><strong><span id="r-ws.10a"
class="auto-hoverlink">R-WS.10a</span></strong> (DEPRECATED) - A
WebSocket client MUST include the <code>Sec-WebSocket-Extensions</code>
header with <code>bbf-usp-protocol</code> WebSocket Extension and
extension parameter <code>eid</code> equal to the client’s Endpoint ID
when initiating a WebSocket session.</p>
<p><em>Note: Requirement <a href="#r-ws.10a"
class="requirement">R-WS.10a</a> was removed in USP 1.3, due to the
impossibility of setting WebSocket Extensions in some
environments.</em></p>
<p><strong><span id="r-ws.10b"
class="auto-hoverlink">R-WS.10b</span></strong> - A WebSocket client
MUST include its Endpoint ID, via a <code>key=value</code> pair, in the
query component of the request URI in its opening handshake, defined in
section 1.3 of RFC 6455 <span class="citation" data-cites="RFC6455"><a
href="#ref-RFC6455" role="doc-biblioref">[19]</a></span>. The
<code>key</code> part of the pair MUST have a value of <code>eid</code>
and the <code>value</code> part MUST be the client’s Endpoint ID. This
pair MUST be separated from other query data by the <code>&amp;</code>
character.</p>
<p><strong><span id="r-ws.11"
class="auto-hoverlink">R-WS.11</span></strong> - A WebSocket server that
supports USP Endpoints MUST include the
<code>Sec-WebSocket-Protocol</code> header for exchange of USP Records
when responding to an initiation of a WebSocket session.</p>
<p><strong><span id="r-ws.11a"
class="auto-hoverlink">R-WS.11a</span></strong> - A WebSocket server
SHOULD include the <code>Sec-WebSocket-Extensions</code> header with
<code>bbf-usp-protocol</code> WebSocket Extension and extension
parameter <code>eid</code> equal to the server’s Endpoint ID when
responding to an initiation of a WebSocket session that includes the
<code>bbf-usp-protocol</code> extension.</p>
<p><strong><span id="r-ws.11b"
class="auto-hoverlink">R-WS.11b</span></strong> - WebSocket clients MUST
NOT consider WebSocket responses that do not include the
<code>bbf-usp-protocol</code> WebSocket Extension to be an error.</p>
<p><strong><span id="r-ws.11c"
class="auto-hoverlink">R-WS.11c</span></strong> - WebSocket servers MUST
NOT consider WebSocket session initiation requests that do not include
the <code>bbf-usp-protocol</code> WebSocket Extension to be an
error.</p>
<p><strong><span id="r-ws.12"
class="auto-hoverlink">R-WS.12</span></strong> - A WebSocket client MUST
NOT establish a WebSocket session if the response to a WebSocket session
initiation request does not include the
<code>Sec-WebSocket-Protocol</code> header for exchange of USP Records
in response to an initiation of a WebSocket session.</p>
<p><strong><span id="r-ws.12a"
class="auto-hoverlink">R-WS.12a</span></strong> - A WebSocket server
MUST NOT establish a WebSocket session if the WebSocket session
initiation request does not include the
<code>Sec-WebSocket-Protocol</code> header.</p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:handling-of-websocket-frames">4.3.3 Handling of WebSocket
Frames</h3>
<p>RFC 6455 defines a number of type of WebSocket control frames (e.g.,
Ping, Pong, Close) and associated condition codes in order to maintain a
WebSocket connection. In addition messages are transferred in WebSocket
Data control frame.</p>
<p><strong><span id="r-ws.13"
class="auto-hoverlink">R-WS.13</span></strong> - A USP Endpoint MUST
implement the WebSocket control frames defined in section 5.5 of RFC
6455 <span class="citation" data-cites="RFC6455"><a href="#ref-RFC6455"
role="doc-biblioref">[19]</a></span>.</p>
<p>USP Records can be transferred between USP Controllers and USP Agents
over an established WebSocket session. These USP Records are
encapsulated within a binary WebSocket data frame as depicted by the
figure below.</p>
<figure id="fig:usp-request-using-a-websocket-session">
<img src="mtp/websocket/USP-request-over-websocket.png"
id="img:usp-request-using-a-websocket-session"
alt="USP Request using a WebSocket Session" />
<figcaption><div class="auto-hoverlink"
data-anchor="fig:usp-request-using-a-websocket-session">
Figure 5: USP Request using a WebSocket Session
</div></figcaption>
</figure>
<p><strong><span id="r-ws.14"
class="auto-hoverlink">R-WS.14</span></strong> - In order for USP
Records to be transferred between a USP Controller and Agent using
WebSockets MUST be encapsulated within as a binary WebSocket data frame
as defined in section 5.6 of RFC 6455 <span class="citation"
data-cites="RFC6455"><a href="#ref-RFC6455"
role="doc-biblioref">[19]</a></span>.</p>
<p><strong><span id="r-ws.15"
class="auto-hoverlink">R-WS.15</span></strong> - USP Records are
transferred between USP Endpoints using message body procedures as
defined in section 6 of RFC 6455 <span class="citation"
data-cites="RFC6455"><a href="#ref-RFC6455"
role="doc-biblioref">[19]</a></span>.</p>
<h4 class="auto-hoverlink" data-info="header"
id="sec:handling-failures-to-deliver-usp-records">4.3.3.1 Handling
Failures to Deliver USP Records</h4>
<p>If a USP Endpoint receives a WebSocket frame containing a USP Record
that cannot be extracted for processing (e.g., text frame instead of a
binary frame, malformed USP Record or USP Record, bad encoding), the
receiving USP Endpoint notifies the originating USP Endpoint that an
error occurred by closing the WebSocket connection with a
<code>1003</code> Status Code with the WebSocket Close frame.</p>
<p><strong><span id="r-ws.16"
class="auto-hoverlink">R-WS.16</span></strong> - A USP Endpoint that
receives a WebSocket frame containing a USP Record that cannot be
extracted for processing, the receiving USP Endpoint MUST terminate the
connection using a WebSocket Close frame with a Status Code of
<code>1003</code>.</p>
<h4 class="auto-hoverlink" data-info="header"
id="sec:keeping-the-websocket-session-alive">4.3.3.2 Keeping the
WebSocket Session Alive</h4>
<p>Once a WebSocket session is established, the WebSocket session is
expected to remain open for future exchanges of USP Records. The
WebSocket protocol uses Ping and Pong control frames as a keep-alive
session. Section 5.5 of RFC 6455 discusses the handling of Ping and Pong
control frames.</p>
<p><strong><span id="r-ws.17"
class="auto-hoverlink">R-WS.17</span></strong> - A USP Agent MUST
implement a WebSocket keep-alive mechanism by periodically sending Ping
control frames and responding to received Ping control frames with Pong
control frames as described in section 5.5 of RFC 6455 <span
class="citation" data-cites="RFC6455"><a href="#ref-RFC6455"
role="doc-biblioref">[19]</a></span>.</p>
<p><strong><span id="r-ws.18"
class="auto-hoverlink">R-WS.18</span></strong> - A USP Agent MUST
provide the capability to assign a keep-alive interval in order to send
Ping control frames to the remote USP Endpoint.</p>
<h4 class="auto-hoverlink" data-info="header"
id="sec:websocket-session-retry">4.3.3.3 WebSocket Session Retry</h4>
<p>If for any reason a WebSocket Session is closed, the USP Endpoint
will attempt to re-establish the WebSocket Session according to its
session retry policy. For Controllers, this session retry policy is
implementation specific.</p>
<p><strong><span id="r-ws.19"
class="auto-hoverlink">R-WS.19</span></strong> – When retrying to
establish a WebSocket Session, the Agent MUST use the following retry
algorithm to manage the WebSocket Session establishment procedure:</p>
<p>For Agents, the retry interval range is controlled by two variables
(described in the table below): the minimum wait interval and the
interval multiplier. The corresponding data model Parameter MAY be
implemented to allow a USP Controller to change the values of these
variables. The factory default values of these variables MUST be the
default values listed in the Default column of the table below.</p>
<table>
<colgroup>
<col style="width: 26%" />
<col style="width: 18%" />
<col style="width: 21%" />
<col style="width: 34%" />
</colgroup>
<thead>
<tr class="header">
<th style="text-align: right;">Descriptive Name</th>
<th style="text-align: center;">Symbol</th>
<th style="text-align: center;">Default</th>
<th style="text-align: left;">Data Model Parameter Name</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: right;">Minimum wait interval</td>
<td style="text-align: center;">m</td>
<td style="text-align: center;">5 seconds</td>
<td
style="text-align: left;"><code>Device.LocalAgent.Controller.{i}.MTP.{i}.WebSocket.SessionRetryMinimumWaitInterval</code></td>
</tr>
<tr class="even">
<td style="text-align: right;">Interval multiplier</td>
<td style="text-align: center;">k</td>
<td style="text-align: center;">2000</td>
<td
style="text-align: left;"><code>Device.LocalAgent.Controller.{i}.MTP.{i}.WebSocket.SessionRetryIntervalMultiplier</code></td>
</tr>
</tbody>
</table>
<table>
<colgroup>
<col style="width: 29%" />
<col style="width: 29%" />
<col style="width: 40%" />
</colgroup>
<thead>
<tr class="header">
<th style="text-align: right;">Retry Count</th>
<th style="text-align: center;">Default Wait Interval Range (min-max
seconds)</th>
<th style="text-align: left;">Actual Wait Interval Range (min-max
seconds)</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: right;">#1</td>
<td style="text-align: center;">5-10</td>
<td style="text-align: left;">m - m.(k/1000)</td>
</tr>
<tr class="even">
<td style="text-align: right;">#2</td>
<td style="text-align: center;">10-20</td>
<td style="text-align: left;">m.(k/1000) - m.(k/1000)^2</td>
</tr>
<tr class="odd">
<td style="text-align: right;">#3</td>
<td style="text-align: center;">20-40</td>
<td style="text-align: left;">m.(k/1000)^2 - m.(k/1000)^3</td>
</tr>
<tr class="even">
<td style="text-align: right;">#4</td>
<td style="text-align: center;">40-80</td>
<td style="text-align: left;">m.(k/1000)^3 - m.(k/1000)^4</td>
</tr>
<tr class="odd">
<td style="text-align: right;">#5</td>
<td style="text-align: center;">80-160</td>
<td style="text-align: left;">m.(k/1000)^4 - m.(k/1000)^5</td>
</tr>
<tr class="even">
<td style="text-align: right;">#6</td>
<td style="text-align: center;">160-320</td>
<td style="text-align: left;">m.(k/1000)^5 - m.(k/1000)^6</td>
</tr>
<tr class="odd">
<td style="text-align: right;">#7</td>
<td style="text-align: center;">320-640</td>
<td style="text-align: left;">m.(k/1000)^6 - m.(k/1000)^7</td>
</tr>
<tr class="even">
<td style="text-align: right;">#8</td>
<td style="text-align: center;">640-1280</td>
<td style="text-align: left;">m.(k/1000)^7 - m.(k/1000)^8</td>
</tr>
<tr class="odd">
<td style="text-align: right;">#9</td>
<td style="text-align: center;">1280-2560</td>
<td style="text-align: left;">m.(k/1000)^8 - m.(k/1000)^9</td>
</tr>
<tr class="even">
<td style="text-align: right;">#10 and subsequent</td>
<td style="text-align: center;">2560-5120</td>
<td style="text-align: left;">m.(k/1000)^9 - m.(k/1000)^10</td>
</tr>
</tbody>
</table>
<p><strong><span id="r-ws.20"
class="auto-hoverlink">R-WS.20</span></strong> – Once a WebSocket
session is established between the Agent and the Controller, the Agent
MUST reset the WebSocket MTP’s retry count to zero for the next
WebSocket Session establishment.</p>
<p><strong><span id="r-ws.21"
class="auto-hoverlink">R-WS.21</span></strong> – If a reboot of the
Agent occurs, the Agent MUST reset the WebSocket MTP’s retry count to
zero for the next WebSocket Session establishment.</p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:mtp-message-encryption-1">4.3.4 MTP Message Encryption</h3>
<p>WebSocket MTP message encryption is provided using certificates in
TLS as described in section 10.5 and section 10.6 of RFC 6455 <span
class="citation" data-cites="RFC6455"><a href="#ref-RFC6455"
role="doc-biblioref">[19]</a></span>.</p>
<p><strong><span id="r-ws.22"
class="auto-hoverlink">R-WS.22</span></strong> - USP Endpoints utilizing
WebSockets clients and servers for message transport MUST implement the
Certificate modes of TLS security as defined in sections 10.5 and 10.6
of RFC 6455 <span class="citation" data-cites="RFC6455"><a
href="#ref-RFC6455" role="doc-biblioref">[19]</a></span>.</p>
<p><strong><span id="r-ws.23"
class="auto-hoverlink">R-WS.23</span></strong> - USP Endpoints capable
of obtaining absolute time SHOULD wait until it has accurate absolute
time before contacting the peer USP Endpoint. If a USP Endpoint for any
reason is unable to obtain absolute time, it can contact the peer USP
Endpoint without waiting for accurate absolute time. If a USP Endpoint
chooses to contact the peer USP Endpoint before it has accurate absolute
time (or if it does not support absolute time), it MUST ignore those
components of the peer USP Endpoint’s WebScoket MTP certificate that
involve absolute time, e.g. not-valid-before and not-valid-after
certificate restrictions.</p>
<p><strong><span id="r-ws.24"
class="auto-hoverlink">R-WS.24</span></strong> - USP Controller
certificates MAY contain domain names with wildcard characters per RFC
6125 <span class="citation" data-cites="RFC6125"><a href="#ref-RFC6125"
role="doc-biblioref">[18]</a></span> guidance.</p>
<h2 class="auto-hoverlink" data-info="header" id="sec:stomp-binding">4.4
STOMP Binding</h2>
<p>The STOMP MTP transfers USP Records between USP endpoints using
version 1.2 of the STOMP protocol <span class="citation"
data-cites="STOMP-1-2"><a href="#ref-STOMP-1-2"
role="doc-biblioref">[40]</a></span>, further referred to as “STOMP
Specification”, or the Simple Text Oriented Message Protocol. Messages
that are transferred between STOMP clients utilize a message bus
interaction model where the STOMP server is the messaging broker that
routes and delivers messages based on the destination included in the
STOMP header.</p>
<p>The following figure depicts the transfer of the USP Records between
USP Agents and Controllers.</p>
<figure id="fig:usp-over-stomp">
<img src="mtp/stomp/STOMP-architecture.jpg"
id="img:usp-over-stomp-architecture"
alt="USP over STOMP Architecture" />
<figcaption><div class="auto-hoverlink"
data-anchor="fig:usp-over-stomp">
Figure 6: USP over STOMP Architecture
</div></figcaption>
</figure>
<p>The basic steps for any USP Endpoint that utilizes a STOMP MTP
are:</p>
<ol type="1">
<li>Negotiate TLS (if required/configured)</li>
<li>Connect to the STOMP Server</li>
<li>Maintain Heart Beats (if configured)</li>
<li>Subscribe to a Destination</li>
<li>Send USP Records</li>
</ol>
<p><strong><span id="r-stomp.0"
class="auto-hoverlink">R-STOMP.0</span></strong> - USP Agents utilizing
STOMP clients for message transport MUST support the
<code>STOMPConn:1</code> and <code>STOMPController:1</code> data model
profiles.</p>
<p><strong><span id="r-stomp.1"
class="auto-hoverlink">R-STOMP.1</span></strong> - USP Agents utilizing
STOMP clients for message transport SHOULD support the
<code>STOMPAgent:1</code> and <code>STOMPHeartbeat:1</code> data model
profile.</p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:handling-of-the-stomp-session">4.4.1 Handling of the STOMP
Session</h3>
<p>When exchanging USP Records across STOMP MTPs, each USP Endpoint
establishes a communications session with a STOMP server. These STOMP
communications sessions are expected to be long lived and are reused for
subsequent exchange of USP Records. A STOMP communications session is
established using a handshake procedure as described in “Connecting a
USP Endpoint to the STOMP Server” section below. A STOMP communications
session is intended to be established as soon as the USP Endpoint
becomes network-aware and is capable of sending TCP/IP messages.</p>
<p>When a STOMP communications session is no longer necessary, the STOMP
connection is closed by the STOMP client, preferably by sending a
<code>DISCONNECT</code> frame (see “Handling Other STOMP Frames” section
below).</p>
<h4 class="auto-hoverlink" data-info="header"
id="sec:connecting-a-usp-endpoint-to-the-stomp-server">4.4.1.1
Connecting a USP Endpoint to the STOMP Server</h4>
<p><strong><span id="r-stomp.2"
class="auto-hoverlink">R-STOMP.2</span></strong> - USP Endpoints
utilizing STOMP clients for message transport MUST send a
<code>STOMP</code> frame to the STOMP server to initiate the STOMP
communications session as defined in the “Connecting” section of the
STOMP Specification.</p>
<p><strong><span id="r-stomp.3"
class="auto-hoverlink">R-STOMP.3</span></strong> - USP Endpoints that DO
NOT utilize client certificate authentication MUST include the login and
passcode STOMP headers in the STOMP frame. For a USP Agent, if the
<code>.STOMP.Connection.{i}.Username</code> Parameter is implemented
then its value will be the source for the <code>login</code> STOMP
header, and if the <code>.STOMP.Connection.{i}.Password</code> Parameter
is implemented then its value will be the source for the
<code>passcode</code> STOMP header.</p>
<p><strong><span id="r-stomp.4"
class="auto-hoverlink">R-STOMP.4</span></strong> - USP Endpoints sending
a <code>STOMP</code> frame MUST include (in addition to other mandatory
STOMP headers) an <code>endpoint-id</code> STOMP header containing the
Endpoint ID of the USP Endpoint sending the frame. <em>Note: According
to the STOMP Specification, the <code>STOMP</code> frame requires that
“C style literal escapes” need to be used to encode any carriage return,
line feed, or colon characters that are found within the UTF-8 encoded
headers, and <a href="#r-stomp.4" class="requirement">R-STOMP.4</a>
requires the Endpoint ID to be included in those headers. Since the
Endpoint ID always contains colon characters, those will need to be
escaped.</em></p>
<p><strong><span id="r-stomp.5"
class="auto-hoverlink">R-STOMP.5</span></strong> - USP Endpoints sending
a STOMP frame MUST include a host STOMP header, if configured to do so.
For a USP Agent the value MUST contain the value from the appropriate
<code>.STOMP.Connection.{i}.VirtualHost</code> Parameter if supported
and not empty.</p>
<p><strong><span id="r-stomp.6"
class="auto-hoverlink">R-STOMP.6</span></strong> - If the USP Endpoint
receives a <code>subscribe-dest</code> STOMP header in the
<code>CONNECTED</code> frame, it MUST use the associated value when
Subscribing to its destination (see “Subscribing a USP Endpoint to a
STOMP Destination” section for more details).</p>
<p><strong><span id="r-stomp.7"
class="auto-hoverlink">R-STOMP.7</span></strong> - If the connection to
the STOMP server is NOT successful then the USP Endpoint MUST enter a
connection retry state. For a USP Agent the retry mechanism is based on
the <code>STOMP.Connection.{i}.</code> retry Parameters:
<code>ServerRetryInitialInterval</code>,
<code>ServerRetryIntervalMultiplier</code>, and
<code>ServerRetryMaxInterval</code>.</p>
<h4 class="auto-hoverlink" data-info="header"
id="sec:handling-the-stomp-heart-beat-mechanism">4.4.1.2 Handling the
STOMP Heart Beat Mechanism</h4>
<p>The STOMP Heart Beat mechanism can be used to periodically send data
between a STOMP client and a STOMP server to ensure that the underlying
TCP connection is still available. This is an optional STOMP mechanism
and is negotiated when establishing the STOMP connection.</p>
<p><strong><span id="r-stomp.8"
class="auto-hoverlink">R-STOMP.8</span></strong> - If the
<code>STOMP.Connection</code> instance’s <code>EnableHeartbeats</code>
Parameter value is true then the USP Agent MUST negotiate the STOMP
Heart Beat mechanism within the <code>STOMP</code> frame during the
process of establishing the STOMP connection as is defined in the
“Heart-beating” section of the STOMP Specification.</p>
<p><strong><span id="r-stomp.9"
class="auto-hoverlink">R-STOMP.9</span></strong> - If the
<code>STOMP.Connection</code> instance’s <code>EnableHeartbeats</code>
Parameter value is either false or not implemented then the USP Agent
MUST either not send the <code>heart-beat</code> STOMP header in the
<code>STOMP</code> frame or send “0,0” as the value of the
<code>heart-beat</code> STOMP header in the <code>STOMP</code>
frame.</p>
<p><strong><span id="r-stomp.10"
class="auto-hoverlink">R-STOMP.10</span></strong> - USP Agents
negotiating the STOMP Heart Beat mechanism MUST use the
<code>STOMP.Connection.{i}.OutgoingHeartbeat</code> and
<code>STOMP.Connection.{i}.IncomingHeartbeat</code> Parameter values
within the <code>heart-beat</code> STOMP header as defined in the
“Heart-beating” section of the STOMP Specification.</p>
<p><strong><span id="r-stomp.11"
class="auto-hoverlink">R-STOMP.11</span></strong> - USP Agents that have
negotiated a STOMP Heart Beat mechanism with a STOMP server MUST adhere
to the heart beat values (as defined in the “Heart-beating” section of
the STOMP Specification) as returned in the <code>CONNECTED</code>
frame.</p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:mapping-usp-endpoints-to-stomp-destinations">4.4.2 Mapping USP
Endpoints to STOMP Destinations</h3>
<p>USP Agents will have one STOMP destination per STOMP MTP independent
of whether those STOMP MTPs use the same <code>STOMP.Connection</code>
instance or a different one. The STOMP destination is either configured
by the STOMP server via the USP custom <code>subscribe-dest</code> STOMP
Header received in the <code>CONNECTED</code> frame (exposed in the
<code>Device.LocalAgent.MTP.{i}.STOMP.DestinationFromServer</code>
Parameter) or taken from the
<code>Device.LocalAgent.MTP.{i}.STOMP.Destination</code> Parameter if
there wasn’t a <code>subscribe-dest</code> STOMP Header received in the
<code>CONNECTED</code> frame. The USP custom <code>subscribe-dest</code>
STOMP Header is helpful in scenarios where the USP Agent doesn’t have a
pre-configured destination as it allows the USP Agent to discover the
destination.</p>
<p>A USP Controller will subscribe to a STOMP destination for each STOMP
server that it is associated with. The USP Controller’s STOMP
destination needs to be known by the USP Agent (this is configured in
the
<code>Device.LocalAgent.Controller.{i}.MTP.{i}.STOMP.Destination</code>
Parameter) as it is used when sending a USP Record containing a
Notification.</p>
<h4 class="auto-hoverlink" data-info="header"
id="sec:subscribing-a-usp-endpoint-to-a-stomp-destination">4.4.2.1
Subscribing a USP Endpoint to a STOMP Destination</h4>
<p><strong><span id="r-stomp.12"
class="auto-hoverlink">R-STOMP.12</span></strong> - USP Endpoints
utilizing STOMP clients for message transport MUST subscribe to their
assigned STOMP destination by sending a <code>SUBSCRIBE</code> frame to
the STOMP server as defined in the “SUBSCRIBE” section of the STOMP
Specification.</p>
<p><strong><span id="r-stomp.13"
class="auto-hoverlink">R-STOMP.13</span></strong> - USP Endpoints
sending a <code>SUBSCRIBE</code> frame MUST include (in addition to
other mandatory STOMP headers) a <code>destination</code> STOMP header
containing the STOMP destination associated with the USP Endpoint
sending the frame.</p>
<p><strong><span id="r-stomp.14"
class="auto-hoverlink">R-STOMP.14</span></strong> - USP Agents that
receive a <code>subscribe-dest</code> STOMP Header in the
<code>CONNECTED</code> frame MUST use that STOMP destination in the
<code>destination</code> STOMP header when sending a
<code>SUBSCRIBE</code> frame.</p>
<p><strong><span id="r-stomp.15"
class="auto-hoverlink">R-STOMP.15</span></strong> - USP Agents that have
NOT received a <code>subscribe-dest</code> STOMP Header in the
<code>CONNECTED</code> frame MUST use the STOMP destination found in the
<code>Device.LocalAgent.MTP.{i}.STOMP.Destination</code> Parameter in
the <code>destination</code> STOMP header when sending a
<code>SUBSCRIBE</code> frame.</p>
<p><strong><span id="r-stomp.16"
class="auto-hoverlink">R-STOMP.16</span></strong> - USP Agents that have
NOT received a <code>subscribe-dest</code> STOMP Header in the
<code>CONNECTED</code> frame and do NOT have a value in the
<code>Device.LocalAgent.MTP.{i}.STOMP.Destination</code> Parameter MUST
terminate the STOMP communications session (preferably via the
<code>DISCONNECT</code> frame) and enter a connection retry state
following <a href="#r-stomp.7" class="requirement">R-STOMP.7</a>.</p>
<p><strong><span id="r-stomp.17"
class="auto-hoverlink">R-STOMP.17</span></strong> - USP Endpoints
sending a <code>SUBSCRIBE</code> frame MUST use an <code>ack</code>
value of “auto”.</p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:mapping-usp-records-to-stomp-frames">4.4.3 Mapping USP Records
to STOMP Frames</h3>
<p>A USP Record is sent from a USP Endpoint to a STOMP Server within a
<code>SEND</code> frame. The STOMP Server delivers that USP Record to
the destination STOMP Endpoint within a <code>MESSAGE</code> frame. When
a USP Endpoint responds to the USP request, the USP Endpoint sends the
USP Record to the STOMP Server within a <code>SEND</code> frame, and the
STOMP Server delivers that USP Record to the destination USP Endpoint
within a <code>MESSAGE</code> frame.</p>
<p><strong><span id="r-stomp.18"
class="auto-hoverlink">R-STOMP.18</span></strong> - USP Endpoints
utilizing STOMP clients for message transport MUST send USP Records in a
<code>SEND</code> frame to the STOMP server as defined in the “SEND”
section of the STOMP Specification.</p>
<p><strong><span id="r-stomp.19"
class="auto-hoverlink">R-STOMP.19</span></strong> - USP Endpoints
sending a <code>SEND</code> frame MUST include (in addition to other
mandatory STOMP headers) a <code>content-length</code> STOMP header
containing the length of the body included in the <code>SEND</code>
frame.</p>
<p><strong><span id="r-stomp.20"
class="auto-hoverlink">R-STOMP.20</span></strong> - USP Endpoints
sending a <code>SEND</code> frame MUST include (in addition to other
mandatory STOMP headers) a <code>content-type</code> STOMP header with a
value of “<code>application/vnd.bbf.usp.msg</code>”, which signifies
that the body included in the <code>SEND</code> frame contains a
Protocol Buffer <span class="citation" data-cites="PROTOBUF"><a
href="#ref-PROTOBUF" role="doc-biblioref">[4]</a></span> binary encoding
message.</p>
<p><strong><span id="r-stomp.21"
class="auto-hoverlink">R-STOMP.21</span></strong> - USP Endpoints
sending a <code>SEND</code> frame with content-type of
<code>application/vnd.bbf.usp.msg</code> MUST include (in addition to
other mandatory STOMP headers) a <code>reply-to-dest</code> STOMP header
containing the STOMP destination that indicates where the USP Endpoint
that receives the USP Record should send any response (if required).</p>
<p><strong><span id="r-stomp.22"
class="auto-hoverlink">R-STOMP.22</span></strong> - USP Endpoints
sending a <code>SEND</code> frame with content-type of
<code>application/vnd.bbf.usp.msg</code> MUST include the Protocol
Buffer <span class="citation" data-cites="PROTOBUF"><a
href="#ref-PROTOBUF" role="doc-biblioref">[4]</a></span> binary encoding
of the USP Record as the body of the <code>SEND</code> frame.</p>
<p><strong><span id="r-stomp.23"
class="auto-hoverlink">R-STOMP.23</span></strong> - When a USP Endpoint
receives a <code>MESSAGE</code> frame it MUST use the
<code>reply-to-dest</code> included in the STOMP headers as the STOMP
destination of the USP response (if a response is required by the
incoming USP request).</p>
<h4 class="auto-hoverlink" data-info="header"
id="sec:handling-errors">4.4.3.1 Handling Errors</h4>
<p>If a STOMP USP Endpoint receives a <code>MESSAGE</code> frame
containing a USP Record that cannot be extracted for processing (e.g.,
text frame instead of a binary frame, malformed USP Record, bad
encoding), it will silently drop the unprocessed USP Record. If the
requirements according to <a href="#sec:usp-record-errors"
class="heading">USP Record Errors</a> are fulfilled, for the STOMP MTP
specifically this means that the <code>reply-to-dest</code> information
has to be available, then a USP Record with an appropriate Error Message
must be created and transmitted via STOMP <code>SEND</code> frame.</p>
<p><em>Note: Error handling was unified between MTPs in USP 1.2 by using
USP Records instead of MTP specific messages, deprecating most of this
section, specifically the requirements <strong><a href="#r-stomp.23a"
class="requirement">R-STOMP.23a</a></strong>, <strong><a
href="#r-stomp.23b" class="requirement">R-STOMP.23b</a></strong>,
<strong><a href="#r-stomp.24"
class="requirement">R-STOMP.24</a></strong>, <strong><a
href="#r-stomp.24a" class="requirement">R-STOMP.24a</a></strong> and
<strong><a href="#r-stomp.24b"
class="requirement">R-STOMP.24b</a></strong>. Please see <a
href="#sec:usp-record-errors" class="heading">USP Record Errors</a> for
details.</em></p>
<p><strong><span id="r-stomp.23a"
class="auto-hoverlink">R-STOMP.23a</span></strong> (DEPRECATED) - USP
Endpoints MUST support STOMP content-type header value of
<code>application/vnd.bbf.usp.error</code>.</p>
<p><em>Note: Requirement <a href="#r-stomp.23a"
class="requirement">R-STOMP.23a</a> was removed in USP 1.2</em></p>
<p><strong><span id="r-stomp.23b"
class="auto-hoverlink">R-STOMP.23b</span></strong> (DEPRECATED) - A USP
Endpoint MUST include a <code>usp-err-id</code> STOMP header in
<code>SEND</code> frames of content-type
<code>application/vnd.bbf.usp.msg</code>. The value of this header is:
<code>&lt;USP Record to_id&gt; + "/" + &lt;USP Message msg_id&gt;</code>,
the <code>&lt;USP Message msg_id&gt;</code> field can be left blank if
the Record does not contain a USP Message. Since the colon
“<code>:</code>” is a reserved character in STOMP headers, all instances
of “<code>:</code>” in the USP Record to_id MUST be expressed using an
encoding of <code>\c</code>.</p>
<p><em>Note: Requirement <a href="#r-stomp.23b"
class="requirement">R-STOMP.23b</a> was removed in USP 1.2</em></p>
<p><strong><span id="r-stomp.24"
class="auto-hoverlink">R-STOMP.24</span></strong> (DEPRECATED) - When a
USP Endpoint receives a <code>MESSAGE</code> frame containing a USP
Record or an encapsulated USP Message within a USP Record that cannot be
extracted for processing, the receiving USP Endpoint MUST ignore the USP
Record if the received STOMP MESSAGE frame did not include a
<code>usp-err-id</code> header.</p>
<p><em>Note: Requirement <a href="#r-stomp.24"
class="requirement">R-STOMP.24</a> was removed in USP 1.2</em></p>
<p><strong><span id="r-stomp.24a"
class="auto-hoverlink">R-STOMP.24a</span></strong> (DEPRECATED) - When a
USP Endpoint receives a MESSAGE frame containing a USP Record or an
encapsulated USP Message within a USP Record that cannot be extracted
for processing, the receiving USP Endpoint MUST send a STOMP SEND frame
with an <code>application/vnd.bbf.usp.error</code> content-type header
value if the received STOMP MESSAGE frame included a
<code>usp-err-id</code> header.</p>
<p><em>Note: Requirement <a href="#r-stomp.24a"
class="requirement">R-STOMP.24a</a> was removed in USP 1.2</em></p>
<p><strong><span id="r-stomp.24b"
class="auto-hoverlink">R-STOMP.24b</span></strong> (DEPRECATED) - A
STOMP SEND frame with <code>application/vnd.bbf.usp.error</code>
content-type MUST contain the received <code>usp-err-id</code> header,
the destination header value set to the received
<code>reply-to-dest</code> header, and a message body (formatted using
UTF-8 encoding) with the following 2 lines:</p>
<ul>
<li><p><code>err_code:&lt;numeric code indicating the type of error that caused the overall message to fail&gt;</code></p></li>
<li><p><code>err_msg:&lt;additional information about the reason behind the error&gt;</code></p></li>
</ul>
<p>The specific error codes are listed in the MTP <a
href="#sec:usp-record-errors" class="heading">USP Record Errors</a>
section.</p>
<p>The following is an example message. This example uses
“<code>^@</code>” to represent the NULL octet that follows a STOMP
body.</p>
<pre><code>SEND
destination:/usp/the-reply-to-dest
content-type:application/vnd.bbf.usp.error
usp-err-id:cid\c3AA3F8\cusp-id-42/683

err_code:7100
err_msg:Field n is not recognized.^@</code></pre>
<p><em>Note: Requirement <a href="#r-stomp.24b"
class="requirement">R-STOMP.24b</a> was removed in USP 1.2</em></p>
<p><strong><span id="r-stomp.25"
class="auto-hoverlink">R-STOMP.25</span></strong> - If an
<code>ERROR</code> frame is received by the USP Endpoint, the STOMP
server will terminate the connection. In this case the USP Endpoint MUST
enter a connection retry state. For a USP Agent the retry mechanism is
based on the <code>STOMP.Connection.{i}.</code> retry Parameters:
<code>ServerRetryInitialInterval</code>,
<code>ServerRetryIntervalMultiplier</code>, and
<code>ServerRetryMaxInterval</code>.</p>
<h4 class="auto-hoverlink" data-info="header"
id="sec:handling-other-stomp-frames">4.4.3.2 Handling Other STOMP
Frames</h4>
<p><strong><span id="r-stomp.26"
class="auto-hoverlink">R-STOMP.26</span></strong> - USP Endpoints
utilizing STOMP clients for message transport MUST NOT send the
transactional STOMP frames including: <code>BEGIN</code>,
<code>COMMIT</code>, and <code>ABORT</code>.</p>
<p><strong><span id="r-stomp.27"
class="auto-hoverlink">R-STOMP.27</span></strong> - USP Endpoints
utilizing STOMP clients for message transport MUST NOT send the
acknowledgement STOMP frames including: <code>ACK</code> and
<code>NACK</code>.</p>
<p><strong><span id="r-stomp.28"
class="auto-hoverlink">R-STOMP.28</span></strong> - USP Endpoints
utilizing STOMP clients for message transport MAY send the following
STOMP frames when shutting down a STOMP connection:
<code>UNSUBSCRIBE</code> (according to the rules defined in the
UNSUBSCRIBE section of the STOMP Specification) and
<code>DISCONNECT</code> (according to the rules defined in the
DISCONNECT section of the STOMP Specification).</p>
<p><strong><span id="r-stomp.29"
class="auto-hoverlink">R-STOMP.29</span></strong> - USP Endpoints
utilizing STOMP clients for message transport that DID NOT receive a
<code>subscribe-dest</code> STOMP Header in the <code>CONNECTED</code>
frame when establishing the STOMP communications session MUST update
their STOMP subscription when their destination is altered by sending
the <code>UNSUBSCRIBE</code> STOMP frame (according to the rules defined
in the UNSUBSCRIBE section of the STOMP Specification) and then
re-subscribing as detailed in the “Subscribing a USP Endpoint to a STOMP
Destination” section.</p>
<p><strong><span id="r-stomp.30"
class="auto-hoverlink">R-STOMP.30</span></strong> - USP Endpoints
utilizing STOMP clients for message transport MAY receive a
<code>RECEIPT</code> frame in which case the STOMP server is
acknowledging that the corresponding client frame has been processed by
the server.</p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:discovery-requirements">4.4.4 Discovery Requirements</h3>
<p>The <a href="#sec:discovery" class="heading">USP Discovery</a>
section details requirements about the general usage of DNS, mDNS, and
DNS-SD records as it pertains to the USP protocol. This section provides
further requirements as to how a USP Endpoint advertises discovery
information when a STOMP MTP is being utilized.</p>
<p><strong><span id="r-stomp.31"
class="auto-hoverlink">R-STOMP.31</span></strong> - When creating a
DNS-SD record, an Endpoint MUST set the DNS-SD “<code>path</code>”
attribute equal to the value of the destination that it has subscribed
to.</p>
<p><strong><span id="r-stomp.32"
class="auto-hoverlink">R-STOMP.32</span></strong> - When creating a
DNS-SD record, an Endpoint MUST utilize the STOMP server’s address
information in the A and AAAA records instead of the USP Endpoint’s
address information.</p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:stomp-server-requirements">4.4.5 STOMP Server Requirements</h3>
<p><strong><span id="r-stomp.33"
class="auto-hoverlink">R-STOMP.33</span></strong> - A STOMP server
implementation MUST adhere to the requirements defined in the STOMP
Specification.</p>
<p><strong><span id="r-stomp.34"
class="auto-hoverlink">R-STOMP.34</span></strong> - A STOMP server
implementation MUST perform authentication of the STOMP client and
ensure that a Remote USP Endpoint is only allowed to subscribe to the
destination that is associated with the USP Endpoint.</p>
<p><strong><span id="r-stomp.35"
class="auto-hoverlink">R-STOMP.35</span></strong> - A STOMP server
implementation SHOULD support both Client Certification Authentication
and Username/Password Authentication mechanisms.</p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:mtp-message-encryption-2">4.4.6 MTP Message Encryption</h3>
<p>STOMP MTP message encryption is provided using TLS certificates.</p>
<p><strong><span id="r-stomp.36"
class="auto-hoverlink">R-STOMP.36</span></strong> - USP Endpoints
utilizing STOMP clients for message transport MUST implement TLS 1.2 RFC
5246 <span class="citation" data-cites="RFC5246"><a href="#ref-RFC5246"
role="doc-biblioref">[33]</a></span> or later with backward
compatibility to TLS 1.2.</p>
<p><strong><span id="r-stomp.37"
class="auto-hoverlink">R-STOMP.37</span></strong> - STOMP server
certificates MAY contain domain names and those domain names MAY contain
domain names with wildcard characters per RFC 6125 <span
class="citation" data-cites="RFC6125"><a href="#ref-RFC6125"
role="doc-biblioref">[18]</a></span> guidance.</p>
<h2 class="auto-hoverlink" data-info="header" id="sec:mqtt-binding">4.5
MQTT Binding</h2>
<p>The Message Queuing Telemetry Transport (MQTT) MTP transfers USP
Records between USP Endpoints using the MQTT protocol. Messages that are
transferred between MQTT clients utilize a message bus interaction model
where the MQTT server is the messaging broker that routes and delivers
messages based on the Topic Name included in the MQTT Publish packet
variable header.</p>
<p>The following figure depicts the transfer of the USP Records between
USP Agents and Controllers.</p>
<figure id="fig:usp-over-mqtt">
<img src="mtp/mqtt/mqtt-architecture.png"
id="img:usp-over-mqtt-architecture" alt="USP over MQTT Architecture" />
<figcaption><div class="auto-hoverlink" data-anchor="fig:usp-over-mqtt">
Figure 7: USP over MQTT Architecture
</div></figcaption>
</figure>
<p>The basic steps for any USP Endpoint that utilizes an MQTT MTP
are:</p>
<ul>
<li>Negotiate TLS (if required/configured)</li>
<li>Connect to the MQTT Server (server may require Authentication)</li>
<li>Subscribe to a Topic</li>
<li>Publish USP Records</li>
<li>Optionally send <code>PINGREQ</code> messages to keep the connection
alive</li>
</ul>
<p>The following figure shows the MQTT packets that have requirements in
this section for their use when MQTT is a USP MTP.</p>
<figure id="fig:mqtt-packets">
<img src="mtp/mqtt/mqtt-packets.png" id="img:mqtt-packets"
alt="MQTT Packets" />
<figcaption><div class="auto-hoverlink" data-anchor="fig:mqtt-packets">
Figure 8: MQTT Packets
</div></figcaption>
</figure>
<p><strong><span id="r-mqtt.1"
class="auto-hoverlink">R-MQTT.1</span></strong> - USP Endpoints
utilizing MQTT clients for message transport MUST implement MQTT 5.0
<span class="citation" data-cites="MQTT-5-0"><a href="#ref-MQTT-5-0"
role="doc-biblioref">[28]</a></span>.</p>
<p><strong><span id="r-mqtt.2"
class="auto-hoverlink">R-MQTT.2</span></strong> - USP Endpoints
utilizing MQTT clients for message transport MAY implement MQTT 3.1.1
<span class="citation" data-cites="MQTT-3-1-1"><a href="#ref-MQTT-3-1-1"
role="doc-biblioref">[27]</a></span>.</p>
<p>Requirements in this MQTT MTP specification are common to both the
MQTT 3.1.1 and MQTT 5.0 specifications unless an MQTT version is
named.</p>
<p>The MQTT specifications are very complete and comprehensive in
describing syntax and usage requirements of MQTT packets and behaviors.
Therefore, none of those requirements are re-iterated in this
specification. This specification only contains requirements unique to
use of MQTT as a USP MTP. The above two requirements for compliance with
the MQTT specifications are critical in developing an implementation
compliant with this MQTT Binding specification. Wherever an MQTT packet
or other functionality is mentioned in the requirements in this MQTT
Binding specification, the requirement for compliance with the MQTT
specification (<a href="#r-mqtt.1" class="requirement">R-MQTT.1</a> and
<a href="#r-mqtt.2" class="requirement">R-MQTT.2</a>) apply.</p>
<p><strong><span id="r-mqtt.3"
class="auto-hoverlink">R-MQTT.3</span></strong> - USP Agents utilizing
MQTT clients for message transport MUST support MQTT over TCP transport
protocol.</p>
<p>The MQTT specification also describes how MQTT can run over
WebSockets. Deployments can choose to use MQTT over WebSockets, if they
use MQTT clients and servers with support for this option. The TCP
option is required to ensure interoperability.</p>
<p><strong><span id="r-mqtt.4"
class="auto-hoverlink">R-MQTT.4</span></strong> - USP Agents utilizing
MQTT clients for message transport MUST support the
<code>MQTTClientCon:1</code>, <code>MQTTClientSubscribe:1</code>,
<code>MQTTAgent:1</code>, and <code>MQTTController:1</code> data model
profiles.</p>
<p><strong><span id="r-mqtt.5"
class="auto-hoverlink">R-MQTT.5</span></strong> - USP Agents utilizing
MQTT clients for message transport SHOULD support the
<code>MQTTClientExtended:1</code> data model profile.</p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:connecting-a-usp-endpoint-to-the-mqtt-server">4.5.1 Connecting a
USP Endpoint to the MQTT Server</h3>
<p>When exchanging USP Records across MQTT MTPs, each USP Endpoint
establishes a communications session with an MQTT server. These MQTT
communications sessions are expected to be long-lived and are re-used
for subsequent exchange of USP Records. An MQTT communications session
is established using the procedure in this section. An MQTT
communications session is intended to be established as soon as the USP
Endpoint becomes network-aware and can send TCP/IP messages.</p>
<p>When an MQTT communications session is no longer necessary or expires
(see “Keep Alive” section below), the MQTT connection is closed by the
MQTT client, preferably by sending a <code>DISCONNECT</code> packet (see
<a href="#sec:handling-other-mqtt-packets" class="heading">Handling
Other MQTT Packets</a> section below).</p>
<p><a href="#r-mqtt.1" class="requirement">R-MQTT.1</a> and <a
href="#r-mqtt.2" class="requirement">R-MQTT.2</a> require that all MQTT
capabilities referenced in this section and its sub-sections are
compliant with the MQTT specifications. Reading the MQTT specification
is highly recommended to ensure the correct syntax and usage of MQTT
packets and properties (<code>CONNECT</code>, <code>CONNACK</code>, User
Name, Password, ClientId, User Property, Keep Alive,
<code>PINGREQ</code>, <code>PINGRESP</code>, etc.).</p>
<p><strong><span id="r-mqtt.6"
class="auto-hoverlink">R-MQTT.6</span></strong> - USP Endpoints
utilizing MQTT clients for message transport MUST send a
<code>CONNECT</code> packet to the MQTT server to initiate the MQTT
communications session.</p>
<p><strong><span id="r-mqtt.7"
class="auto-hoverlink">R-MQTT.7</span></strong> - USP Endpoints with a
configured MQTT User Name and Password for use with this MQTT server
MUST include these in the MQTT <code>CONNECT</code> packet. The
<code>.MQTT.Client.{i}.Username</code> and
<code>.MQTT.Client.{i}.Password</code> Parameter values (associated with
this MQTT server) will be used for User Name and Password.</p>
<p><strong><span id="r-mqtt.8"
class="auto-hoverlink">R-MQTT.8</span></strong> - USP Endpoints MUST set
the value of the <code>CONNECT</code> packet Client Identifier
(ClientId) as follows:</p>
<ul>
<li>If a non-empty, non-null ClientId value exists for use with this
MQTT server, this MUST be used. The data model Parameter for the
ClientId is <code>.MQTT.Client.{i}.ClientID</code>.</li>
<li>If an MQTT 5.0 client has no configured ClientId (null or empty
string) the USP Endpoint MUST send an empty string in the Client
Identifier property.</li>
<li>If an MQTT 3.1.1 client has no configured ClientId, the USP Endpoint
SHOULD attempt to use its USP Endpoint ID as the ClientId.</li>
</ul>
<p><strong><span id="r-mqtt.9"
class="auto-hoverlink">R-MQTT.9</span></strong> - An MQTT 5.0 client
MUST save (in the <code>.MQTT.Client.{i}.ClientID</code> Parameter) an
Assigned Client Identifier included in a <code>CONNACK</code> packet as
its configured ClientId for future connections to the MQTT server.</p>
<p><strong><span id="r-mqtt.10"
class="auto-hoverlink">R-MQTT.10</span></strong> - If the connection to
the MQTT server is NOT successful then the USP Endpoint MUST enter a
connection retry state. For a USP Agent the retry mechanism is based on
the <code>MQTT.Client.{i}.</code> retry Parameters:
<code>ConnectRetryTime</code>,
<code>ConnectRetryIntervalMultiplier</code>, and
<code>ConnectRetryMaxInterval</code>.</p>
<p><strong><span id="r-mqtt.11"
class="auto-hoverlink">R-MQTT.11</span></strong> - Once a USP Endpoint
has successfully connected to an MQTT server, it MUST use the same
ClientId for all subsequent connections with that server.</p>
<h4 class="auto-hoverlink" data-info="header"
id="sec:connect-flags-and-properties">4.5.1.1 CONNECT Flags and
Properties</h4>
<p>The MQTT <code>CONNECT</code> packet has a number of flags and
properties that can be set. The User Name and Password flags are set to
1 if these parameters are included. The use of the Will Retain, Will
QoS, and Will Flag are left up to the deployment. They are not needed in
order to use MQTT as a USP MTP and can be “0” if there is no
deployment-specified need for them. The Clean Start flag can also be
used according to deployment-specified needs. Configured values for
these flags can be provided through the related
<code>.MQTT.Client.{i}.</code> Parameters.</p>
<p>MQTT 3.1.1 does not provide a simple mechanism for a USP MQTT client
to provide its Endpoint ID to the MQTT server. But the server does have
other options, such as:</p>
<ol type="1">
<li>Support Endpoint ID as ClientId.</li>
<li>Get Endpoint ID from client TLS certificate.</li>
</ol>
<p>MQTT 3.1.1 also does not provide a mechanism for the MQTT server to
tell a client what Topic other Endpoints should use to send the client a
message (the “reply to” Topic). This information would need to be
pre-configured or provided in some manner not specified here.</p>
<p>MQTT 5.0 includes additional properties that deployments can choose
to use.</p>
<p><strong><span id="r-mqtt.12"
class="auto-hoverlink">R-MQTT.12</span></strong> - An MQTT 5.0 USP
Endpoint MUST support setting the Request Response Information property
to 1, and MUST support receiving the corresponding Response Information
in the <code>CONNACK</code> packet.</p>
<p>The Response Information property is used by an MQTT 5.0 client as
the Response Topic (which is the MQTT 5.0 <code>PUBLISH</code> packet
property identifying the Topic to send a USP response to). The Response
Information property requirements for use of the received Response
Information are below in <a
href="#sec:sending-the-usp-record-in-a-publish-packet-payload"
class="heading">Sending the USP Record in a PUBLISH Packet Payload</a>.
Ensuring the client is subscribed to this Topic or a Topic Filter that
includes this Topic is described in <a
href="#sec:subscribing-to-mqtt-topics" class="heading">Subscribing to
MQTT Topics</a>.</p>
<p><strong><span id="r-mqtt.13"
class="auto-hoverlink">R-MQTT.13</span></strong> - An MQTT 5.0 USP
Endpoint MUST include a User Property name-value pair in the
<code>CONNECT</code> packet with name of “usp-endpoint-id” and value of
this Endpoint’s USP Endpoint ID.</p>
<h4 class="auto-hoverlink" data-info="header"
id="sec:keep-alive">4.5.1.2 Keep Alive</h4>
<p>The MQTT Keep Alive mechanism has several components:</p>
<ul>
<li>The <code>CONNECT</code> packet Keep Alive field tells the server to
disconnect the client if the server does not receive a packet from the
client before the Keep Alive time (in seconds) has elapsed since the
prior received packet.</li>
<li>The MQTT 5.0 <code>CONNACK</code> packet Keep Alive field allows the
server to inform the client the maximum interval the server will allow
to elapse between received packets before it disconnects the client due
to inactivity.</li>
<li><code>PINGREQ</code> and <code>PINGRESP</code> packets can be used
to keep the connection up if the timer is nearing expiry and there is no
need for another type of message. <code>PINGREQ</code> can also be used
by the client at any time to check on the status of the connection.</li>
</ul>
<p>The client can indicate the Server is not required to disconnect the
Client on the grounds of inactivity by setting the <code>CONNECT</code>
Keep Alive to zero (0). Note that WebSockets mechanisms can be used to
keep the connection alive if MQTT is being run over WebSockets. Also
note the server is allowed to disconnect the client at any time,
regardless of Keep Alive value.</p>
<p><strong><span id="r-mqtt.14"
class="auto-hoverlink">R-MQTT.14</span></strong> - USP Endpoints with a
configured Keep Alive value MUST include this in the MQTT
<code>CONNECT</code> packet. The
<code>.MQTT.Client.{i}.KeepAliveTime</code> Parameter value (associated
with this MQTT server) will be used for the Keep Alive value.</p>
<p>Use of <code>PINGREQ</code> and <code>PINGRESP</code> for keeping
sessions alive (or determining session aliveness) is as described in the
MQTT specification. No additional requirements are provided for use of
these packets in a USP context.</p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:subscribing-to-mqtt-topics">4.5.2 Subscribing to MQTT
Topics</h3>
<p>The <code>SUBSCRIBE</code> packet is sent by the MQTT client to
subscribe to one or more Topics or Topic Filters. These are needed to
allow the MQTT client to receive application messages. The MQTT client
will receive all application messages published by other clients that
are sent to a Topic that matches (either exactly or within a wildcarded
Topic Filter) a subscribed-to Topic or Topic Filter. The MQTT server
indicates in the <code>SUBACK</code> response packet whether the client
has succeeded or failed to subscribe to each Topic or Topic Filter sent
in the <code>SUBSCRIBE</code> packet.</p>
<p>USP Endpoints can be configured with one or more specific MQTT Topics
or Topic Filters to subscribe to for each MQTT server they are
associated with. In MQTT 5.0, a <code>CONNACK</code> User Property named
“subscribe-topic” can be used to provide the client with Topic or Topic
Filter values for the client to subscribe to. There is no similar
capability in MQTT 3.1.1. This means configuration or some out-of-band
mechanism are the only means of supplying subscription Topics or Topic
Filters to an MQTT 3.1.1 client. An Agent will need to be configured
with a Controller’s MQTT Topic (the
<code>Device.LocalAgent.Controller.{i}.MTP.{i}.MQTT.Topic</code>
Parameter is used to configure this), to send a Notification to that
Controller.</p>
<p><span id="r-mqtt.1-1" class="auto-hoverlink">R-MQTT.1</span> and <a
href="#r-mqtt.2" class="requirement">R-MQTT.2</a> require that all MQTT
capabilities referenced in this section and its sub-sections are
compliant with the MQTT specifications. Reading the MQTT specification
is highly recommended to ensure the correct syntax and usage of MQTT
packets and properties (<code>SUBSCRIBE</code>, Topic Filter, QoS 0, QoS
1, QoS 2, etc.).</p>
<p><strong><span id="r-mqtt.15"
class="auto-hoverlink">R-MQTT.15</span></strong> - USP Endpoints that
successfully connect to an MQTT server MUST send a
<code>SUBSCRIBE</code> packet with all Topic Filters identified in the
following list:</p>
<ul>
<li>All configured Topic Filter values for use with this MQTT server
MUST be included in a <code>SUBSCRIBE</code> packet. For a USP Agent,
the <code>.MQTT.Client.{i}.Subscription.{i}.</code> table can be used to
configure Topic Filter values.</li>
<li>If an MQTT 5.0 USP Endpoint received one or more User Property in
the <code>CONNACK</code> packet where the name of the name-value pair is
“subscribe-topic”, the USP Endpoint MUST include the value of all such
name-value pairs in its <code>SUBSCRIBE</code> packet as a Topic
Filter.</li>
<li>If an MQTT 5.0 Endpoint received a Response Information property in
the <code>CONNACK</code> packet, and the topic from that Response
Information property is not included (directly or as a subset of a Topic
Filter) among the Topic Filters of the previous 2 bullets, the Endpoint
MUST include the value of the Response Information property in its
<code>SUBSCRIBE</code> packet.</li>
<li>If a USP Agent has a <code>ResponseTopicConfigured</code> value and
did not receive a Response Information property in the
<code>CONNACK</code> packet, and the topic in the
<code>ResponseTopicConfigured</code> Parameter is not included (directly
or as a subset of a Topic Filter) among the Topic Filters of the first 2
bullets, the Agent MUST include the value of the
<code>ResponseTopicConfigured</code> in its <code>SUBSCRIBE</code>
packet. For MQTT 5.0 clients, the subscription topic is set to the value
of <code>ResponseTopicConfigured</code>. For MQTT 3.1.1 clients, the
subscription topic is set to a wildcarded topic filter based on the
value of <code>ResponseTopicConfigured</code>.</li>
</ul>
<p><strong><span id="r-mqtt.16"
class="auto-hoverlink">R-MQTT.16</span></strong> - USP Agents that have
NOT received any Subscriptions outlined in <a href="#r-mqtt.15"
class="requirement">R-MQTT.15</a> “subscribe-topic” User Property in the
<code>CONNACK</code> and do NOT have a configured Topic Filter
(<code>Device.MQTT.Client.{i}.Subscription.{i}.Topic</code> Parameter
for this Client instance in the data model) MUST terminate the MQTT
communications session (via the <code>DISCONNECT</code> packet) and
consider the MTP disabled.</p>
<p><strong><span id="r-mqtt.17"
class="auto-hoverlink">R-MQTT.17</span></strong> - If a USP Endpoint
does not successfully subscribe to at least one Topic, it MUST NOT
publish a packet with a USP Record in its Application Message, and MUST
disconnect from the MQTT server.</p>
<p>For each Topic listed in a <code>SUBSCRIBE</code> packet, the client
will also provide a desired QoS level. See the MQTT specification (MQTT
3.1.1 <span class="citation" data-cites="MQTT-3-1-1"><a
href="#ref-MQTT-3-1-1" role="doc-biblioref">[27]</a></span> or MQTT 5.0
<span class="citation" data-cites="MQTT-5-0"><a href="#ref-MQTT-5-0"
role="doc-biblioref">[28]</a></span>, Section 4.3) for description of
the three QoS levels (QoS 0, QoS 1, QoS 2). The usefulness of these QoS
levels in the context of USP depends on the particulars of the MQTT
deployment. It is therefore up to the implementer / deployer to decide
which QoS setting to use. In order to ensure deployments have the
ability to use at least QoS 1, MQTT clients and servers are required to
implement at least QoS 1 (see requirements in <a
href="#sec:sending-the-usp-record-in-a-publish-packet-payload"
class="heading">Sending the USP Record in a PUBLISH Packet Payload</a>
and <a href="#sec:mqtt-server-requirements" class="heading">MQTT Server
Requirements</a>).</p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:sending-the-usp-record-in-a-publish-packet-payload">4.5.3
Sending the USP Record in a PUBLISH Packet Payload</h3>
<p>A USP Record is sent from a USP Endpoint to an MQTT Server within a
<code>PUBLISH</code> packet payload. The MQTT Server delivers that
<code>PUBLISH</code> packet to the destination MQTT client USP Endpoint.
This is true of all USP Message types.</p>
<p><span id="r-mqtt.1-2" class="auto-hoverlink">R-MQTT.1</span> and <a
href="#r-mqtt.2" class="requirement">R-MQTT.2</a> require that all MQTT
capabilities referenced in this section and its sub-sections are
compliant with the MQTT specifications. Reading the MQTT specification
is highly recommended to ensure the correct syntax and usage of MQTT
packets and properties (<code>PUBLISH</code>, Content Type, Response
Topic, etc.).</p>
<p><strong><span id="r-mqtt.18"
class="auto-hoverlink">R-MQTT.18</span></strong> - USP Endpoints
utilizing MQTT clients for message transport MUST send the USP Record in
the payload of a <code>PUBLISH</code> packet.</p>
<p><strong><span id="r-mqtt.19"
class="auto-hoverlink">R-MQTT.19</span></strong> - USP Endpoints MUST
send USP Records using the Protocol Buffer <span class="citation"
data-cites="PROTOBUF"><a href="#ref-PROTOBUF"
role="doc-biblioref">[4]</a></span> binary encoding of the USP
Record.</p>
<p><strong><span id="r-mqtt.20"
class="auto-hoverlink">R-MQTT.20</span></strong> - USP Endpoints
utilizing MQTT clients for message transport MUST support MQTT QoS 0 and
QoS 1.</p>
<p>The USP Controller’s MQTT Topic needs to be known by any USP Agent
expected to send a Notify message to the Controller.</p>
<p>The USP Agent will also need to know an exact Topic where it can be
reached (and not just a Topic Filter) in order to provide a Controller
with the Agent’s “reply to” Topic.</p>
<p><strong><span id="r-mqtt.21"
class="auto-hoverlink">R-MQTT.21</span></strong> - An MQTT 5.0 USP
Endpoint that receives Response Information in the <code>CONNACK</code>
packet MUST use this as its “reply to” Topic.</p>
<p><em>Note: By using a single “reply to” Topic for all USP connections,
an Agent on the MQTT server may become a DoS attack vector and cannot be
unsubscribed from because this would cause the Agent to lose all “reply
to” traffic. </em></p>
<p><strong><span id="r-mqtt.22"
class="auto-hoverlink">R-MQTT.22</span></strong> - USP Endpoints MUST
include a “reply to” Topic in all <code>PUBLISH</code> packets
transporting USP Records.</p>
<p><strong><span id="r-mqtt.23"
class="auto-hoverlink">R-MQTT.23</span></strong> - USP Endpoints using
MQTT 5.0 MUST include their “reply to” Topic in the <code>PUBLISH</code>
Response Topic property.</p>
<p><strong><span id="r-mqtt.24"
class="auto-hoverlink">R-MQTT.24</span></strong> - USP Endpoints using
MQTT 3.1.1 MUST include their “reply to” Topic after “/reply-to=” at the
end of the <code>PUBLISH</code> Topic Name, with any “/” character in
the Topic replaced by “%2F”.</p>
<p>For example, if a Controller’s “reply to” Topic is
“usp/controllers/oui:00256D:my-unique-bbf-id-42”, and it is sending to
an Agent whose Topic is “usp/agents/cid:3AA3F8:my-unique-usp-id-42”, the
<code>PUBLISH</code> Topic Name for a USP Controller using an MQTT 3.1.1
client will be “usp/agents/cid:3AA3F8:my-unique-usp-id-42/reply-to=
usp%2Fcontrollers%2Foui:00256D:my-unique-bbf-id-42”.</p>
<p>USP Endpoints that need to send a response to a received USP Record
will need to determine the Topic Name to use in the responding
<code>PUBLISH</code> packet.</p>
<p><strong><span id="r-mqtt.25"
class="auto-hoverlink">R-MQTT.25</span></strong> - USP Endpoints using
MQTT 3.1.1 MUST interpret the portion of the received
<code>PUBLISH</code> Topic Name following the last forward slash
“/reply-to=” as the response Topic Name. Any instance of “%2F” in this
received string MUST be replaced with “/”.</p>
<p><strong><span id="r-mqtt.26"
class="auto-hoverlink">R-MQTT.26</span></strong> - USP Endpoints using
MQTT 5.0 MUST use the received <code>PUBLISH</code> Response Topic
property as the response Topic Name.</p>
<p>When an USP Endpoint receives a MQTT 3.1.1 <code>PUBLISH</code>
packet without “reply to” Topic or a USP <code>Connect</code> Record
with a different MQTT version indicated in the <code>version</code>
field of the <code>mqtt_connect</code> Record type, then a MQTT version
mismatch between brokers involved in the MQTT communication has
occurred.</p>
<p><strong><span id="r-mqtt.26a"
class="auto-hoverlink">R-MQTT.26a</span></strong> - If a MQTT version
mismatch is encountered and the sender “reply to” Topic is known, the
receiving Endpoint MUST handle this error according to <a
href="#sec:mqtt-handling-errors" class="heading">Handling Errors</a> and
cease communication until the mismatch has been addressed by the
sender.</p>
<p><strong><span id="r-mqtt.27"
class="auto-hoverlink">R-MQTT.27</span></strong> - USP Endpoints sending
a USP Record using MQTT 5.0 MUST have “usp.msg” in the Content Type
property.</p>
<p>MQTT clients using MQTT 3.1.1 will need to know to pass the payload
to the USP Agent for handling. There is no indication in MQTT 3.1.1 of
the payload application or encoding. an MQTT 3.1.1 deployment could
choose to dedicate the MQTT connection to USP, or put something in the
syntax of <code>PUBLISH</code> packet Topic Names that would indicate
the payload is a USP Record.</p>
<p><strong><span id="r-mqtt.27a"
class="auto-hoverlink">R-MQTT.27a</span></strong> - USP Endpoints
receiving a MQTT 5.0 <code>PUBLISH</code> packet MUST interpret the
Content Type property of “usp.msg” or “application/vnd.bbf.usp.msg” (the
registered USP Record MIME type) as indicating the packet contains a USP
Record.</p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:mqtt-handling-errors">4.5.4 Handling Errors</h3>
<p>The MQTT specification requires servers and clients to disconnect if
there is a violation at the MQTT protocol layer.</p>
<p>If a MQTT USP Endpoint receives a <code>PUBLISH</code> packet
containing a USP Record that cannot be extracted for processing
(e.g. malformed USP Record or bad encoding), it will silently drop the
unprocessed USP Record. If the requirements according to <a
href="#sec:usp-record-errors" class="heading">USP Record Errors</a> are
fulfilled, then a USP Record with an appropriate Error Message will be
created and published.</p>
<p><em>Note: Error handling was unified between MTPs in USP 1.2 by using
USP Records instead of MTP specific messages, deprecating most of this
section, specifically <strong><a href="#r-mqtt.28"
class="requirement">R-MQTT.28</a></strong>, <strong><a href="#r-mqtt.29"
class="requirement">R-MQTT.29</a></strong>, <strong><a href="#r-mqtt.30"
class="requirement">R-MQTT.30</a></strong>, <strong><a href="#r-mqtt.31"
class="requirement">R-MQTT.31</a></strong>, <strong><a
href="#r-mqtt.31a" class="requirement">R-MQTT.31a</a></strong> and
<strong><a href="#r-mqtt.32" class="requirement">R-MQTT.32</a></strong>.
Please see <a href="#sec:usp-record-errors" class="heading">USP Record
Errors</a> for details.</em></p>
<p><strong><span id="r-mqtt.28"
class="auto-hoverlink">R-MQTT.28</span></strong> (DEPRECATED) - MQTT 5.0
Endpoints MUST support <code>PUBLISH</code> Content Type value of
“usp.error”.</p>
<p><em>Note: Requirement <a href="#r-mqtt.28"
class="requirement">R-MQTT.28</a> was removed in USP 1.2</em></p>
<p><strong><span id="r-mqtt.29"
class="auto-hoverlink">R-MQTT.29</span></strong> (DEPRECATED) - MQTT 5.0
Endpoints MUST include a <code>usp-err-id</code> MQTT User Property in
<code>PUBLISH</code> packets of content-type “usp.msg”. The value of
this User Property is:
<code>&lt;USP Record to_id&gt; + "/" + &lt;USP Message msg_id&gt;</code>,
the <code>&lt;USP Message msg_id&gt;</code> field can be left blank if
the Record does not contain a USP Message.</p>
<p><em>Note: Requirement <a href="#r-mqtt.29"
class="requirement">R-MQTT.29</a> was removed in USP 1.2</em></p>
<p><strong><span id="r-mqtt.30"
class="auto-hoverlink">R-MQTT.30</span></strong> (DEPRECATED) - When an
MQTT 3.1.1 USP Endpoint receives a <code>PUBLISH</code> packet
containing a USP Record or an encapsulated USP Message within a USP
Record that cannot be extracted for processing, the receiving USP
Endpoint MUST silently drop the USP Record.</p>
<p><em>Note: Requirement <a href="#r-mqtt.30"
class="requirement">R-MQTT.30</a> was removed in USP 1.2</em></p>
<p><strong><span id="r-mqtt.31"
class="auto-hoverlink">R-MQTT.31</span></strong> (DEPRECATED) - When an
MQTT 5.0 USP Endpoint receives a <code>PUBLISH</code> packet containing
a USP Record or an encapsulated USP Message within a USP Record that
cannot be extracted for processing and the <code>PUBLISH</code> packet
contains a <code>usp-err-id</code> header, the receiving USP Endpoint
MUST send a <code>PUBLISH</code> packet with Content Type “usp.error”, a
User Property set to the received <code>usp-err-id</code> User Property,
the Topic Name set to the received Response Topic, and a
<code>PUBLISH</code> Payload (formatted using UTF-8 encoding) with the
following 2 lines:</p>
<ul>
<li><code>err_code:</code>&lt;numeric code indicating the type of error
that caused the overall message to fail&gt;</li>
<li><code>err_msg:</code>&lt;additional information about the reason
behind the error&gt;</li>
</ul>
<p>The specific error codes are listed in the MTP <a
href="#sec:usp-record-errors" class="heading">USP Record Errors</a>
section.</p>
<p>MQTT 5.0 includes a Reason Code that is used to respond to
<code>PUBLISH</code> packets when QoS 1 or QoS 2 is used.</p>
<p><em>Note: Requirement <a href="#r-mqtt.31"
class="requirement">R-MQTT.31</a> was removed in USP 1.2</em></p>
<p><strong><span id="r-mqtt.31a"
class="auto-hoverlink">R-MQTT.31a</span></strong> (DEPRECATED) - USP
Endpoints receiving a MQTT 5.0 <code>PUBLISH</code> packet MUST
interpret the Content Type property of “usp.error” or
“application/vnd.bbf.usp.error” (the registered USP error message MIME
type) as indicating the packet contains a USP error message and
code.</p>
<p><em>Note: Requirement <a href="#r-mqtt.31a"
class="requirement">R-MQTT.31a</a> was removed in USP 1.2</em></p>
<p><strong><span id="r-mqtt.32"
class="auto-hoverlink">R-MQTT.32</span></strong> (DEPRECATED) - When a
USP Endpoint using MQTT 5.0 receives a <code>PUBLISH</code> packet with
QoS 1 or QoS 2 containing a USP Record or an encapsulated USP Message
within a USP Record that cannot be extracted for processing, the
receiving USP Endpoint MUST include Reason Code 153 (0x99) identifying
“Payload format invalid” in any <code>PUBACK</code> or
<code>PUBREC</code> packet.</p>
<p>Note these packets will be received by the MQTT server and will not
be forwarded to the USP Endpoint that originally sent the USP
Record.</p>
<p><em>Note: Requirement <a href="#r-mqtt.32"
class="requirement">R-MQTT.32</a> was removed in USP 1.2</em></p>
<p><strong><span id="r-mqtt.33"
class="auto-hoverlink">R-MQTT.33</span></strong> - If the MQTT server
terminates the connection, the USP Endpoint MUST enter a connection
retry state. For a USP Agent the retry mechanism is based on the
MQTT.Client.{i}. <code>ConnectRetryTime</code> Parameter.</p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:handling-other-mqtt-packets">4.5.5 Handling Other MQTT
Packets</h3>
<p>Use of <code>PUBREL</code>, and <code>PUBCOMP</code> depends on the
QoS level being used for the subscribed Topic. No additional
requirements are provided for use of these packets in a USP context.</p>
<p>Use of <code>PINGREQ</code> and <code>PINGRESP</code> for keeping
sessions alive (or determining session aliveness) is as described in the
MQTT specification. No additional requirements are provided for use of
these packets in a USP context.</p>
<p>Use of <code>UNSUBSCRIBE</code> and <code>UNSUBACK</code> is as
described in the MQTT specification. If an Agent’s configured Topics are
disabled by a Controller (by setting
Device.MQTT.Client.{i}.Subscription.{i}.Enable to “false”),
<code>UNSUBSCRIBE</code> is used to unsubscribe from them.</p>
<p><strong><span id="r-mqtt.34"
class="auto-hoverlink">R-MQTT.34</span></strong> - USP Endpoints
utilizing MQTT clients for message transport SHOULD send an
<code>UNSUBSCRIBE</code> packet when a subscribed Topic or Topic Filter
is no longer indicated but the MQTT connection is expected to stay
up.</p>
<p><span id="r-mqtt.1-3" class="auto-hoverlink">R-MQTT.1</span> and <a
href="#r-mqtt.2" class="requirement">R-MQTT.2</a> require that all MQTT
capabilities referenced in this section and its sub-sections are
compliant with the MQTT specifications. Reading the MQTT specification
is highly recommended to ensure the correct syntax and usage of MQTT
packets and properties (<code>DISCONNECT</code>, etc.).</p>
<p><strong><span id="r-mqtt.35"
class="auto-hoverlink">R-MQTT.35</span></strong> - USP Endpoints
utilizing MQTT clients for message transport SHOULD send a
<code>DISCONNECT</code> packet when shutting down an MQTT
connection.</p>
<p>MQTT 5.0 specifies the <code>AUTH</code> packet to use for extended
authentication. Implementations can make use of extended authentication
but should only do so if they are sure that all clients and servers will
support the same authentication mechanisms.</p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:discovery-requirements-1">4.5.6 Discovery Requirements</h3>
<p>The USP discovery section details requirements about the general
usage of DNS, mDNS, and DNS-SD records as it pertains to the USP
protocol. This section provides further requirements as to how a USP
Endpoint advertises discovery information when an MQTT MTP is being
utilized.</p>
<p><strong><span id="r-mqtt.36"
class="auto-hoverlink">R-MQTT.36</span></strong> - When creating a
DNS-SD record (<a href="#sec:dns-sd-records" class="heading">DNS-SD
Records</a>), an Agent MUST set the DNS-SD “path” attribute equal to the
value of its “reply to” Topic.</p>
<p><strong><span id="r-mqtt.37"
class="auto-hoverlink">R-MQTT.37</span></strong> - When creating a
DNS-SD record (<a href="#sec:dns-sd-records" class="heading">DNS-SD
Records</a>), a Controller MUST set the DNS-SD “path” attribute equal to
a value that is included among the Controller’s subscribed Topics and
Topic Filters.</p>
<p><strong><span id="r-mqtt.38"
class="auto-hoverlink">R-MQTT.38</span></strong> - When creating a
DNS-SD record, an Endpoint MUST utilize the MQTT server’s address
information in the A and AAAA records instead of the USP Endpoint’s
address information.</p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:mqtt-server-requirements">4.5.7 MQTT Server Requirements</h3>
<p><strong><span id="r-mqtt.39"
class="auto-hoverlink">R-MQTT.39</span></strong> - MQTT servers MUST
implement MQTT 5.0 <span class="citation" data-cites="MQTT-5-0"><a
href="#ref-MQTT-5-0" role="doc-biblioref">[28]</a></span>.</p>
<p><strong><span id="r-mqtt.40"
class="auto-hoverlink">R-MQTT.40</span></strong> - MQTT servers SHOULD
implement MQTT 3.1.1 <span class="citation" data-cites="MQTT-3-1-1"><a
href="#ref-MQTT-3-1-1" role="doc-biblioref">[27]</a></span>.</p>
<p><strong><span id="r-mqtt.41"
class="auto-hoverlink">R-MQTT.41</span></strong> - MQTT servers MUST
implement MQTT over TCP transport protocol.</p>
<p><strong><span id="r-mqtt.42"
class="auto-hoverlink">R-MQTT.42</span></strong> - An MQTT server MUST
support authentication of the MQTT client through at least one of the
mechanisms described in Section 5.4.1 of the MQTT specification, and
support an Access Control List mechanism that can restrict the topics an
authenticated MQTT client can subscribe or publish to.</p>
<p><strong><span id="r-mqtt.43"
class="auto-hoverlink">R-MQTT.43</span></strong> - An MQTT server SHOULD
support both Client Certification Authentication and User Name /
Password Authentication mechanisms.</p>
<p><strong><span id="r-mqtt.44"
class="auto-hoverlink">R-MQTT.44</span></strong> - An MQTT server SHOULD
support sending Topic or Topic Filter values in a “subscribe-topic” User
Property in the <code>CONNACK</code> packet.</p>
<p><strong><span id="r-mqtt.45"
class="auto-hoverlink">R-MQTT.45</span></strong> - If an MQTT server
supports subscriptions from unconfigured Agents, it MUST support
wildcarded Topic Filters.</p>
<p>This will allow support for Agents that try to subscribe to
“+/&lt;Endpoint ID&gt;/#” and “+/+/&lt;Endpoint ID&gt;/#” Topic
Filters.</p>
<p><strong><span id="r-mqtt.46"
class="auto-hoverlink">R-MQTT.46</span></strong> - An MQTT server MUST
support at least MQTT QoS 1 level.</p>
<p><strong><span id="r-mqtt.47"
class="auto-hoverlink">R-MQTT.47</span></strong> - An MQTT server SHOULD
support a ClientId value that is a USP Endpoint ID. This includes
supporting all Endpoint ID characters (includes “-”, “.”, “_”, “%”, and
“:”) and at least 64 characters length.</p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:mtp-message-encryption-3">4.5.8 MTP Message Encryption</h3>
<p>MQTT MTP message encryption is provided using TLS certificates.</p>
<p><strong><span id="r-mqtt.48"
class="auto-hoverlink">R-MQTT.48</span></strong> - USP Endpoints
utilizing MQTT clients for message transport MUST implement TLS 1.2
<span class="citation" data-cites="RFC5246"><a href="#ref-RFC5246"
role="doc-biblioref">[33]</a></span> or later with backward
compatibility to TLS 1.2.</p>
<p><strong><span id="r-mqtt.49"
class="auto-hoverlink">R-MQTT.49</span></strong> - MQTT server
certificates MAY contain domain names and those domain names MAY contain
domain names with wildcard characters per RFC 6125 <span
class="citation" data-cites="RFC6125"><a href="#ref-RFC6125"
role="doc-biblioref">[18]</a></span> guidance.</p>
<h2 class="auto-hoverlink" data-info="header"
id="sec:unix-domain-socket">4.6 UNIX Domain Socket Binding</h2>
<p>This is an internal Message Transfer Protocol (MTP) for communicating
between a USP Agent and a USP Controller that reside on separate
processes within a single device. This MTP uses UNIX domain sockets to
send Frames between the UNIX domain socket clients and servers. The
Frame contains a Header field and one or more Type-Length-Value (TLV)
fields to transport USP Records and other information related to the use
of this transport as a USP MTP.</p>
<figure id="fig:unix-domain-socket-binding">
<img src="mtp/unix-domain-socket/unix-domain-socket-binding.png"
id="img:unix-domain-socket-binding" alt="Unix Domain Socket Binding" />
<figcaption><div class="auto-hoverlink"
data-anchor="fig:unix-domain-socket-binding">
Figure 9: Unix Domain Socket Binding
</div></figcaption>
</figure>
<h3 class="auto-hoverlink" data-info="header"
id="sec:handling-unix-domain-socket-connections">4.6.1 Handling UNIX
Domain Socket Connections</h3>
<p>UNIX domain socket concepts are broken down into two key aspects:
server and client. A UNIX domain socket server is responsible for
listening on an UNIX domain socket for incoming connections and then
accepting those connections such that the server can then send and
receive messages over the connection. A UNIX domain socket client is
responsible for establishing a connection to a server such that the
client can then send and receive messages over the established
communications session.</p>
<p>UNIX domain sockets are different than other sockets as they aren’t
governed by a host and port. Instead, the UNIX domain socket is
associated to a local file path (and its internal file descriptor).</p>
<p>A USP Agent communicating over UNIX domain sockets as the USP MTP can
act as either a UNIX domain socket server or a UNIX domain socket
client, but not both.</p>
<p>A USP Controller communicating over UNIX domain sockets as the USP
MTP can act as either a UNIX domain socket server or a UNIX domain
socket client, but not both.</p>
<p>Since UNIX domain sockets and this type of internal MTP is completely
contained within the device itself, there is no need to advertise the
USP Agent or USP Controller details via mDNS.</p>
<p><strong><span id="r-uds.1"
class="auto-hoverlink">R-UDS.1</span></strong> - USP Agents utilizing
UNIX domain socket servers or clients for message transport MUST support
the UDSAgent:1 and UDSController:1 data model profiles.</p>
<h4 class="auto-hoverlink" data-info="header"
id="sec:establishing-a-unix-domain-socket-connection">4.6.1.1
Establishing a UNIX Domain Socket Connection</h4>
<p>This section contains requirements related to setting up a UNIX
domain socket connection between a USP Agent and a USP Controller that
reside on two separate processes within the same device.</p>
<p><strong><span id="r-uds.2"
class="auto-hoverlink">R-UDS.2</span></strong> - A USP Endpoint acting
as a UNIX domain socket server MUST bind to a UNIX domain socket and
listen for incoming connections.</p>
<p><strong><span id="r-uds.3"
class="auto-hoverlink">R-UDS.3</span></strong> - A USP Endpoint acting
as a UNIX domain socket server MUST accept incoming connections from
UNIX domain socket clients.</p>
<p>To get to this point, a connection to the server’s listen socket must
be made from the USP Endpoint acting as a UNIX domain socket client.</p>
<p><strong><span id="r-uds.4"
class="auto-hoverlink">R-UDS.4</span></strong> - A USP Endpoint acting
as a UNIX domain socket client MUST connect to a known UNIX domain
socket server.</p>
<p>At this point we have a bidirectional UNIX domain socket connection,
which can be used to send USP Records between a USP Agent and a USP
Controller.</p>
<h4 class="auto-hoverlink" data-info="header"
id="sec:retrying-a-unix-domain-socket-connection">4.6.1.2 Retrying a
UNIX Domain Socket Connection</h4>
<p>UNIX domain sockets don’t often get disconnected after the connection
has been established on both ends, but there are cases where a retry
algorithm is valuable:</p>
<ul>
<li>Many UNIX domain socket clients are simultaneously attempting to
establish a connection with the UNIX domain socket server, and that
limit exceeds the “backlog” value that the UNIX domain socket server
used when calling the “listen” system call.</li>
<li>A UNIX domain socket is terminated by the USP Agent or USP
Controller due to some failure to deliver or handle a frame message (see
Section 4.6.2.1 Handling Failures to Handshake, Section 4.6.3.1 Handling
Failures to Deliver USP Records, Section 4.6.5 Handling Other UNIX
Domain Socket Failures, and Section 4.6.6 Error Handling)</li>
</ul>
<p>If for any reason a UNIX domain socket connection fails to be
established or is closed, the USP Endpoint acting as a client will
attempt to re-establish the UNIX domain socket connection.</p>
<p><strong><span id="r-uds.5"
class="auto-hoverlink">R-UDS.5</span></strong> - When a UNIX domain
socket connection is closed or fails to be established, the USP Endpoint
acting as a client MUST attempt to re-establish the UNIX domain socket
within a random amount of time between 1 and 5 seconds.</p>
<h4 class="auto-hoverlink" data-info="header"
id="sec:sending-a-message-over-a-unix-domain-socket">4.6.1.3 Sending a
Message over a UNIX Domain Socket</h4>
<p>This MTP uses UNIX domain sockets to send Frames between the UNIX
domain socket clients and servers. The UNIX domain socket Frame contains
a Header field and one or more Type-Length-Value (TLV) fields to
transport the information related to the use of this transport as a USP
MTP. The Header field contains a Synchronization part (which includes
the hexadecimal version of “_USP”) and a Length part that contains the
length of the remainder of the Frame (i.e. the length of the entire
Frame excluding the size of the Header). The Type part of the TLV field
will always be 1 byte, the Length part of the TLV field will always be 4
bytes, and the Value part of the TLV field is based on the Type.</p>
<p><strong><span id="r-uds.6"
class="auto-hoverlink">R-UDS.6</span></strong> - A Frame sent across a
UNIX domain socket that is being used as an MTP MUST have a Header field
and one or more TLV fields.</p>
<p><strong><span id="r-uds.7"
class="auto-hoverlink">R-UDS.7</span></strong> - The Header of a Frame
sent across a UNIX domain socket that is being used as an MTP MUST have
a synchronization part and a length part.</p>
<p><strong><span id="r-uds.8"
class="auto-hoverlink">R-UDS.8</span></strong> - The synchronization
portion of the Frame’s Header MUST contain the following 4 bytes: 0x5f
0x55 0x53 0x50 (the hexadecimal version of “_USP”).</p>
<p><strong><span id="r-uds.9"
class="auto-hoverlink">R-UDS.9</span></strong> - The length portion of
the Frame’s Header MUST contain the length of the remainder of the Frame
(i.e. the length of the entire Frame excluding the size of the Header)
as a 4 byte unsigned integer in network byte order.</p>
<p><strong><span id="r-uds.10"
class="auto-hoverlink">R-UDS.10</span></strong> - A TLV field contained
in a Frame sent across a UNIX domain socket that is being used as an MTP
MUST have a 1 byte Type.</p>
<p><strong><span id="r-uds.11"
class="auto-hoverlink">R-UDS.11</span></strong> - A TLV field contained
in a Frame sent across a UNIX domain socket that is being used as an MTP
MUST have a 4 byte Length in network byte order.</p>
<p>The following set of Types are defined as allowable types in the TLV
fields:</p>
<table>
<colgroup>
<col style="width: 14%" />
<col style="width: 30%" />
<col style="width: 54%" />
</colgroup>
<thead>
<tr class="header">
<th style="text-align: left;">Type</th>
<th style="text-align: left;">Name</th>
<th style="text-align: left;">Description of Value</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;"><code>1</code></td>
<td style="text-align: left;">Handshake</td>
<td style="text-align: left;">The Handshake contains a UTF-8 string that
represents the Endpoint ID of the USP Endpoint sending the message.</td>
</tr>
<tr class="even">
<td style="text-align: left;"><code>2</code></td>
<td style="text-align: left;">Error</td>
<td style="text-align: left;">The Error contains a UTF-8 string that
provides the error message related to the communications failure.</td>
</tr>
<tr class="odd">
<td style="text-align: left;"><code>3</code></td>
<td style="text-align: left;">USP Record</td>
<td style="text-align: left;">The USP Record contains the Google
Protocol Buffer binary-encoded USP Record being sent between a USP Agent
and USP Controller.</td>
</tr>
</tbody>
</table>
<p><strong><span id="r-uds.12"
class="auto-hoverlink">R-UDS.12</span></strong> - A Frame sent across a
UNIX domain socket that is being used as an MTP MUST contain a TLV with
Type 1 for any Handshake negotiation messages</p>
<p><strong><span id="r-uds.13"
class="auto-hoverlink">R-UDS.13</span></strong> - A Frame sent across a
UNIX domain socket that is being used as an MTP MUST contain a TLV with
Type 2 for any Error messages</p>
<p><strong><span id="r-uds.14"
class="auto-hoverlink">R-UDS.14</span></strong> - A Frame sent across a
UNIX domain socket that is being used as an MTP MUST contain a TLV with
Type 3 for any USP Record messages</p>
<p><strong><span id="r-uds.15"
class="auto-hoverlink">R-UDS.15</span></strong> - A Frame sent across a
UNIX domain socket that is being used as an MTP MUST ignore any TLVs
that have unexpected Types</p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:handshaking-with-unix-domain-sockets">4.6.2 Handshaking with
UNIX Domain Sockets</h3>
<p>After a UNIX domain socket is established between a server (either a
USP Agent acting as a server or a USP Controller acting as a server) and
a client (either a USP Agent acting as a client or a USP Controller
acting as a client), the USP Endpoints need to exchange Handshake Frames
to provide each other with their identities because every USP Record
contains the from and to Endpoint ID. This means that both the USP Agent
and USP Controller will send a Frame with a Type 1 TLV and their own
Endpoint ID before sending any USP Record across the newly established
UNIX domain socket connection.</p>
<p><strong><span id="r-uds.16"
class="auto-hoverlink">R-UDS.16</span></strong> - A USP Endpoint acting
as a UNIX domain socket client MUST send a Unix domain socket Frame
containing a Type 1 (Handshake) TLV field once it establishes a UNIX
domain socket connection. This message MUST contain the Endpoint ID of
the USP Endpoint sending the message.</p>
<p><strong><span id="r-uds.17"
class="auto-hoverlink">R-UDS.17</span></strong> - A USP Endpoint acting
as a UNIX domain socket server MUST send a Unix domain socket Frame
containing a Type 1 (Handshake) TLV field once it receives a Unix domain
socket Frame containing a Type 1 (Handshake) TLV field from a USP
Endpoint acting as a UNIX domain socket client. This message MUST
contain the Endpoint ID of the USP Endpoint sending the message.</p>
<p><strong><span id="r-uds.18"
class="auto-hoverlink">R-UDS.18</span></strong> - A USP Endpoint acting
as a UNIX domain socket client MUST terminate the UNIX domain socket
connection if it doesn’t receive a Unix domain socket Frame containing a
Type 1 (Handshake) TLV field within 30 seconds of when it sent its own
Unix domain socket Frame containing a Type 1 (Handshake) TLV field.</p>
<p>Once both sides of the UNIX domain socket have successfully completed
the handshake process, which is done by the USP Agent and the USP
Controller exchanging Unix domain socket Frames that contain a Type 1
(Handshake) TLV field, then either the USP Agent or USP Controller may
begin sending USP Record messages.</p>
<p><strong><span id="r-uds.19"
class="auto-hoverlink">R-UDS.19</span></strong> - A USP Endpoint acting
as a UNIX domain socket client or server MUST ignore an unexpected UNIX
domain socket Frame that contains a Type 2 (Handshake) TLV field.</p>
<p><strong><span id="r-uds.20"
class="auto-hoverlink">R-UDS.20</span></strong> - A USP Endpoint acting
as a UNIX domain socket client or server MUST ignore any UNIX domain
socket Frames that contain a Type 3 (USP Record) TLV field until it has
successfully completed the handshake process.</p>
<p>The following image shows an example of a UNIX domain socket Frame
that contains a Type 1 (Handshake) TLV field used for handshaking
between a USP Agent and USP Controller. In this example, the Endpoint ID
being used is “os::00256D-0123456789”.</p>
<figure id="fig:unix-domain-socket-frame-with-handshake-message">
<img src="mtp/unix-domain-socket/./USP-UDS-Handshake.png"
id="img:unix-domain-socket-frame-with-handshake-message"
alt="UNIX Domain Socket Frame with Handshake Message" />
<figcaption><div class="auto-hoverlink"
data-anchor="fig:unix-domain-socket-frame-with-handshake-message">
Figure 10: UNIX Domain Socket Frame with Handshake Message
</div></figcaption>
</figure>
<h4 class="auto-hoverlink" data-info="header"
id="sec:handling-failures-to-handshake">4.6.2.1 Handling Failures to
Handshake</h4>
<p>If for any reason the handshake process fails on one side of the UNIX
domain socket or the other, then the side that fails the handshake
process is responsible for sending a UNIX domain socket Frame containing
an Error (using a Type 2 TLV field) that explains why the handshake
process has failed .</p>
<p><strong><span id="r-uds.21"
class="auto-hoverlink">R-UDS.21</span></strong> - A USP Endpoint acting
as a UNIX domain socket client or server MUST send a UNIX domain socket
Frame containing a Type 2 (Error) TLV field if it can not process an
incoming UNIX domain socket Frame that contains a Type 1 (Handshake) TLV
field.</p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:sending-usp-records-across-unix-domain-sockets">4.6.3 Sending
USP Records across UNIX Domain Sockets</h3>
<p>Once a UNIX domain socket is established between a server (either a
USP Agent acting as a server or a USP Controller acting as a server) and
a client (either a USP Agent acting as a client or a USP Controller
acting as a client), and the USP Endpoints have successfully completed
the handshake process, then either the USP Agent or USP Controller may
begin sending UNIX domain socket Frames that contain a USP Record. A USP
Endpoint sends a USP Record by sending a UNIX domain socket Frame with a
Type 3 (USP Record) TLV field that contains the Google Protocol Buffer
binary-encoded USP Record across the established UNIX domain socket
connection.</p>
<p><strong><span id="r-uds.22"
class="auto-hoverlink">R-UDS.22</span></strong> - A USP Endpoint MUST
send Google Protocol Buffer binary-encoded USP Records by utilizing a
UNIX domain socket Frame that contains a Type 3 (USP Record) TLV
field.</p>
<p>The following image shows an example of a UNIX domain socket Frame
that contains a Type 3 (USP Record) TLV field, which is used for sending
a USP Record between a USP Agent and USP Controller.</p>
<figure id="fig:unix-domain-socket-frame-with-usp-record-message">
<img src="mtp/unix-domain-socket/./USP-UDS-Record.png"
id="img:unix-domain-socket-frame-with-usp-record-message"
alt="UNIX Domain Socket Frame with USP Record Message" />
<figcaption><div class="auto-hoverlink"
data-anchor="fig:unix-domain-socket-frame-with-usp-record-message">
Figure 11: UNIX Domain Socket Frame with USP Record Message
</div></figcaption>
</figure>
<h4 class="auto-hoverlink" data-info="header"
id="sec:handling-failures-to-deliver-usp-records-1">4.6.3.1 Handling
Failures to Deliver USP Records</h4>
<p>If a USP Endpoint acting as a UNIX domain socket client or server
receives a UNIX domain socket Frame that contains a USP Record that
cannot be extracted for processing (e.g., a UNIX domain socket Frame
that includes a Type 3 TLV with text instead of a binary data, a
malformed USP Record), a UNIX domain socket Frame containing a Type 2
(Error) TLV field is sent in response and the UNIX domain socket
connection gets closed.</p>
<p><strong><span id="r-uds.23"
class="auto-hoverlink">R-UDS.23</span></strong> - A USP Endpoint acting
as a UNIX domain socket client or server MUST send a UNIX domain socket
Frame containing a Type 2 (Error) TLV field and terminate the UNIX
Domain Socket connection, if it receives an incoming UNIX domain socket
Frame containing a USP Record that cannot be extracted for
processing.</p>
<p>Other USP Record processing failures (where the USP Record can be
extracted, but other issues exist) are handled by <a href="#r-mtp.5"
class="requirement">R-MTP.5</a>.</p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:mtp-message-encryption-4">4.6.4 MTP Message Encryption</h3>
<p>Encryption is not required for the UNIX domain socket MTP as all
messages are exchanged between processes that reside internally within
the device.</p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:handling-other-unix-domain-socket-failures">4.6.5 Handling Other
UNIX Domain Socket Failures</h3>
<p>If a USP Endpoint acting as a UNIX domain socket client or server
receives a TLV Message that cannot be parsed, a UNIX domain socket Frame
containing a Type 2 (Error) TLV field is sent in response and the UNIX
domain socket connection gets closed.</p>
<p><strong><span id="r-uds.24"
class="auto-hoverlink">R-UDS.24</span></strong> - A USP Endpoint acting
as a UNIX domain socket client or server MUST send a UNIX domain socket
Frame containing a Type 2 (Error) TLV field and terminate the UNIX
Domain Socket connection, if it can not parse an incoming UNIX domain
socket Frame.</p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:error-handling">4.6.6 Error Handling</h3>
<p>If a USP Endpoint receives a UNIX domain socket Frame containing a
Type 2 (Error) TLV field, then it closes the UNIX domain socket
connection.</p>
<p><strong><span id="r-uds.25"
class="auto-hoverlink">R-UDS.25</span></strong> - A USP Endpoint acting
as a UNIX domain socket client or server that receives a UNIX domain
socket Frame containing a Type 2 (Error) TLV field MUST terminate the
UNIX domain socket connection.</p>
<h1 class="auto-hoverlink" data-info="header" id="sec:encoding">5
Message Encoding</h1>
<p>USP requires a mechanism to serialize data to be sent over a Message
Transfer Protocol. The description of each individual Message and the
USP Record encoding scheme is covered in a section of this document
and/or in the referenced specification. This version of the
specification includes support for:</p>
<ul>
<li>Protocol Buffers Version 3 <span class="citation"
data-cites="PROTOBUF"><a href="#ref-PROTOBUF"
role="doc-biblioref">[4]</a></span></li>
</ul>
<p><strong><span id="r-enc.0"
class="auto-hoverlink">R-ENC.0</span></strong> - An implementation using
protocol buffers encoding to encode USP Messages (Requests, Responses,
and Errors) MUST conform to the schema defined in <a
href="../specification/usp-msg-1-3.proto">usp-msg-1-3.proto</a>.</p>
<p><strong><span id="r-enc.1"
class="auto-hoverlink">R-ENC.1</span></strong> - An implementation using
protocol buffers encoding to encode USP Records MUST conform to the
schema defined in <a
href="../specification/usp-record-1-3.proto">usp-record-1-3.proto</a>.</p>
<p>Protocol Buffers Version 3 uses a set of enumerated elements to
coordinate encoding and decoding during transmission. It is intended
that these remain backwards compatible, but new versions of the schema
may contain new enumerated elements.</p>
<p><strong><span id="r-enc.2"
class="auto-hoverlink">R-ENC.2</span></strong> - If an Endpoint receives
a USP payload containing an unknown enumeration value for a known field,
the Endpoint MUST report the failure as described in <a href="#r-mtp.5"
class="requirement">R-MTP.5</a>.</p>
<p>Protocol Buffers uses a datatype called <code>oneof</code>. This
means that the element contains elements of one or more varying
types.</p>
<p><strong><span id="r-enc.3"
class="auto-hoverlink">R-ENC.3</span></strong> - USP Records and USP
Messages that contain an element of type <code>oneof</code> MUST include
1 and only 1 instance of the element, which MUST contain one of the
possible elements.</p>
<p><strong><span id="r-enc.4"
class="auto-hoverlink">R-ENC.4</span></strong> - A USP Record that
violates <a href="#r-enc.3" class="requirement">R-ENC.3</a> MUST be
discarded.</p>
<p><strong><span id="r-enc.5"
class="auto-hoverlink">R-ENC.5</span></strong> - A USP Message that
violates <a href="#r-enc.3" class="requirement">R-ENC.3</a> SHOULD
return an error of type 7004 (Invalid Arguments).</p>
<h2 class="auto-hoverlink" data-info="header"
id="sec:parameter-value-encoding">5.1 Parameter and Argument Value
Encoding</h2>
<p><a href="../specification/usp-msg-1-3.proto">usp-msg-1-3.proto</a>
specifies that Parameter and argument values in USP Messages are
represented as Protocol Buffers Version 3 strings (which are
UTF-8-encoded).</p>
<p>This section specifies how Parameter and argument values are
converted to and from Protocol Buffers Version 3 strings.</p>
<p><strong><span id="r-enc.6"
class="auto-hoverlink">R-ENC.6</span></strong> - Parameter and argument
values MUST be converted to and from Protocol Buffers Version 3 strings
using the string representations of the TR-106 Appendix I.4 <span
class="citation" data-cites="TR-106"><a href="#ref-TR-106"
role="doc-biblioref">[2]</a></span> data types.</p>
<p>TR-106 Appendix I.4 states that “Parameters make use of a limited
subset of the default SOAP data types”. The SOAP 1.1 specification <span
class="citation" data-cites="SOAP-1-1"><a href="#ref-SOAP-1-1"
role="doc-biblioref">[29]</a></span> states that all SOAP simple types
are defined by the XML Schema Part 2: Datatypes specification <span
class="citation" data-cites="XMLSCHEMA-2"><a href="#ref-XMLSCHEMA-2"
role="doc-biblioref">[30]</a></span>, and this is the ultimate
reference.</p>
<p>In practice there should be few surprises, e.g., XML Schema Part 2,
Section 3.3.22 <span class="citation" data-cites="XMLSCHEMA-2"><a
href="#ref-XMLSCHEMA-2" role="doc-biblioref">[30]</a></span> states that
it has a lexical representation consisting of a finite-length sequence
of decimal digits (#x30-#x39).</p>
<p>Some of the encoding rules are quite complicated, e.g. SOAP 1.1,
Section 5.2.3 <span class="citation" data-cites="SOAP-1-1"><a
href="#ref-SOAP-1-1" role="doc-biblioref">[29]</a></span> states that
<code>base64</code> line length restrictions don’t apply to SOAP, and
XML Schema Part 2, Section 3.2.7 <span class="citation"
data-cites="XMLSCHEMA-2"><a href="#ref-XMLSCHEMA-2"
role="doc-biblioref">[30]</a></span> has a lot of detail about which
aspects of ISO 8601 are and are not supported by the
<code>dateTime</code> data type.</p>
<h1 class="auto-hoverlink" data-info="header"
id="sec:e2e-message-exchange">6 End to End Message Exchange</h1>
<p>USP Messages are exchanged between Controllers and Agents. In some
deployment scenarios, the Controller and Agent have a direct connection.
In other deployment scenarios, the messages exchanged by the Controller
and Agent traverse multiple intermediate MTP Proxies. The latter
deployment scenario typically occurs when the Agent or Controller is
deployed outside the proximal or Local Area Network. In both types of
scenarios, the End-to-End (E2E) message exchange capabilities of USP
permit the:</p>
<ul>
<li>Exchange of USP Records within an E2E Session Context that allows
for:
<ul>
<li>Integrity protection for non-payload fields</li>
<li>Protected and unprotected payloads</li>
<li>Segmentation and reassembly of E2E Messages that would be too large
to transfer through the intermediate MTP Proxies.</li>
</ul></li>
<li>Exchange of USP Records without an E2E Session Context that allows
for:
<ul>
<li>Integrity protection for non-payload fields</li>
<li>Unprotected payloads or protected payloads where the payload
protection security mechanism doesn’t require a concept of a session
(e.g., COSE)</li>
</ul></li>
</ul>
<p>Protected payloads provide a secure message exchange
(confidentiality, integrity and identity authentication) through
exchange of USP Messages that are secured by the originating and
receiving USP Endpoints.</p>
<p>USP makes use of USP Records to exchange USP Messages between
Endpoints, see <a href="#sec:record-definition" class="heading">Record
Definition</a> for a description of the USP Record fields.</p>
<p><strong><span id="r-e2e.1"
class="auto-hoverlink">R-E2E.1</span></strong> - A receiving USP
Endpoint MUST ignore any Record that does not contain its own Endpoint
Identifier as the <code>to_id</code> field of the Record.</p>
<p><strong><span id="r-e2e.2"
class="auto-hoverlink">R-E2E.2</span></strong> – A USP Record with
record_type = session_context MUST contain at least one
<code>payload</code> field, or a non-zero <code>retransmit_id</code>.
(DEPRECATED)</p>
<p><em>Note: the R-E2E.2 requirement was deprecated in USP 1.2, because
sending a Session Context Record without a payload is useful for
restarting a Session Context</em></p>
<p><em>Note: the requirements below reference Objects and Parameters
used to manage the E2E Session. These are specified in the Device:2 Data
Model <span class="citation" data-cites="TR-181"><a href="#ref-TR-181"
role="doc-biblioref">[3]</a></span>.</em></p>
<p><em>Note: The USP Record Encapsulation section was moved to <a
href="#sec:usp-record-encapsulation" class="heading">USP Record
Encapsulation</a> in USP 1.2.</em></p>
<h2 class="auto-hoverlink" data-info="header"
id="sec:exchange-of-usp-records-within-an-e2e-session-context">6.1
Exchange of USP Records within an E2E Session Context</h2>
<p>When exchanging USP Records within an E2E Session Context,
<code>record_type</code> of <code>session_context</code> is used, and
all required parameters for <code>record_type</code> of
<code>session_context</code> are supplied.</p>
<p>When a USP Record that is received within an E2E Session Context
contains a USP Message request, its associated response or error message
is sent within an E2E Session Context, unless otherwise specified (see
<a href="#sec:requests-responses-and-errors" class="heading">Requests,
Responses and Errors</a>).</p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:establishing-an-e2e-session-context">6.1.1 Establishing an E2E
Session Context</h3>
<p>For the exchange of USP Records within an E2E Session Context to
happen between two USP Endpoints, an E2E Session Context (Session
Context) is established between the participating USP Endpoints. The
Session Context is uniquely identified within the USP Endpoint by the
combination of the Session Identifier and remote USP Endpoint’s
Identifier.</p>
<p>In USP, either a Controller or an Agent can begin the process of
establishing a Session Context. This is done by the Controller or Agent
sending a USP Record with a <code>session_id</code> field that is not
currently associated with the Agent/Controller combination and a
<code>sequence_id</code> field value of <code>1</code>. Note that a
Record with an empty payload can be used to establish a new Session
Context.</p>
<p><strong><span id="r-e2e.3"
class="auto-hoverlink">R-E2E.3</span></strong> – Session Context
identifiers MUST be generated by the USP Endpoint that originates the
session such that it is greater than 1 and scoped to the remote USP
Endpoint.</p>
<p>When a Session Context had been previously established between an
Agent and Controller and the remote USP Endpoint receives a USP Record
with a different <code>session_id</code> field, the remote USP Endpoint
will restart the Session Context using the new <code>session_id</code>
field.</p>
<p><strong><span id="r-e2e.4"
class="auto-hoverlink">R-E2E.4</span></strong> – When a USP Endpoint
receives a USP Record from another USP Endpoint where there is no
established Session Context, and the USP Record includes a Session
Context identifier, and the USP Endpoint is configured to allow Session
Context to be used with the other Endpoint, the USP Endpoint MUST start
a new Session Context for the remote USP Endpoint, and initialize the
<code>sequence_id</code> field to <code>1</code>.</p>
<p><strong><span id="r-e2e.5"
class="auto-hoverlink">R-E2E.5</span></strong> – At most one (1) Session
Context is established between an Agent and Controller.</p>
<p><strong><span id="r-e2e.6"
class="auto-hoverlink">R-E2E.6</span></strong> – When a USP Endpoint
receives a USP Record from a remote USP Endpoint with a different
Session Context identifier than was previously established, the
receiving USP Endpoint MUST start a new Session Context for the remote
USP Endpoint, using the <code>session_id</code> from the received USP
Record, and initialize the <code>sequence_id</code> field to
<code>1</code>.</p>
<p><em>Note: Implementations need to consider if outstanding USP
Messages that have not been transmitted to the remote USP Endpoint need
to be transmitted within the newly established Session Context.</em></p>
<p><strong><span id="r-e2e.6a"
class="auto-hoverlink">R-E2E.6a</span></strong> – When an Agent is
configured not to allow Session Context or does not support Session
Context and receives a USP Record initiating Session Context, the Agent
MUST reply with a Disconnect Record and MUST include reason_code and
reason fields indicating Session Context is not allowed (code 7106 from
<a href="#sec:usp-record-errors" class="heading">USP Record
Errors</a>).</p>
<p>When a Controller is configured to require Session Context and
receives a Disconnect Record indicating Session Context is not allowed
or supported by the Agent, the Controller is expected to terminate the
MTP session.</p>
<p><strong><span id="r-e2e.6b"
class="auto-hoverlink">R-E2E.6b</span></strong> – If an Agent needs to
terminate a Session Context without terminating an existing MTP
connection where Session Context is being used, it MUST send a
Disconnect Record and MUST include reason_code and reason indicating
Session Context is being terminated (code 7105 from <a
href="#sec:usp-record-errors" class="heading">USP Record
Errors</a>).</p>
<h4 class="auto-hoverlink" data-info="header"
id="sec:session-context-expiration">6.1.1.1 Session Context
Expiration</h4>
<p>Sessions Contexts have a lifetime and can expire. The expiration of
the Session Context is handled by the
<code>Device.LocalAgent.Controller.{i}.E2ESession.SessionExpiration</code>
Parameter in the Agent. If the Agent does not see activity (an exchange
of USP Records) within the Session Context, the Agent considers the
Session Context expired and for the next interaction with the Controller
a new Session Context is established.</p>
<p><strong><span id="r-e2e.7"
class="auto-hoverlink">R-E2E.7</span></strong> – When a Session Context
between a Controller or Agent expires the Agent MUST initiate a new
Session Context upon the next interaction with the remote USP Endpoint
or from a Session Context request by the remote USP Endpoint.</p>
<h4 class="auto-hoverlink" data-info="header"
id="sec:exhaustion-of-sequence-identifiers">6.1.1.2 Exhaustion of
Sequence Identifiers</h4>
<p>USP Endpoints identify the USP Record using the
<code>sequence_id</code> field. When the <code>sequence_id</code> field
for a USP Record that is received or transmitted by a USP Endpoint nears
the maximum value that can be handled by the USP Endpoint, the USP
Endpoint will attempt to establish a new Session Context in order to
avoid a rollover of the <code>sequence_id</code> field.</p>
<p><strong><span id="r-e2e.8"
class="auto-hoverlink">R-E2E.8</span></strong> – When a USP Endpoint
receives a USP Record with a value of the <code>sequence_id</code> field
that is within 10,000 of the maximum size for the data type of the
<code>sequence_id</code> field, the USP Endpoint MUST establish a new
Session Context with the remote USP Endpoint.</p>
<p><strong><span id="r-e2e.9"
class="auto-hoverlink">R-E2E.9</span></strong> – When a USP Endpoint
transmits a USP Record with a value of the <code>sequence_id</code>
field that is within 10,000 of the maximum size for the data type of the
<code>sequence_id</code> field, the USP Endpoint MUST establish a new
Session Context with the remote USP Endpoint upon its next contact with
the remote USP Endpoint.</p>
<h4 class="auto-hoverlink" data-info="header"
id="sec:failure-handling-in-the-session-context">6.1.1.3 Failure
Handling in the Session Context</h4>
<p>In some situations, (e.g., TLS negotiation handshake) the failure to
handle a received USP Record is persistent, causing an infinite cycle of
“receive
failure/request-&gt;session/establish-&gt;session/receive-&gt;failure”
to occur. In these situations, the Agent enforces a policy as defined in
this section regarding establishment of failed Session Contexts or
failed interactions within a Session Context. The policy is controlled
by the <code>Device.LocalAgent.Controller.{i}.E2ESession.Enable</code>
Parameter.</p>
<p><strong><span id="r-e2e.10"
class="auto-hoverlink">R-E2E.10</span></strong> – When retrying USP
Records, the Agent MUST use the following retry algorithm to manage the
retransmission Session Context establishment procedure:</p>
<p>The retry interval range is controlled by two Parameters, the minimum
wait interval and the interval multiplier, each of which corresponds to
a data model Parameter, and which are described in the table below. The
factory default values of these Parameters MUST be the default values
listed in the Default column. They MAY be changed by a Controller with
the appropriate permissions at any time.</p>
<table>
<colgroup>
<col style="width: 18%" />
<col style="width: 5%" />
<col style="width: 7%" />
<col style="width: 68%" />
</colgroup>
<thead>
<tr class="header">
<th style="text-align: right;">Descriptive Name</th>
<th style="text-align: center;">Symbol</th>
<th style="text-align: center;">Default</th>
<th style="text-align: left;">Data Model Parameter Name</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: right;">Minimum wait interval</td>
<td style="text-align: center;">m</td>
<td style="text-align: center;">5 seconds</td>
<td
style="text-align: left;"><code>Device.LocalAgent.Controller.{i}.E2ESession.SessionRetryMinimumWaitInterval</code></td>
</tr>
<tr class="even">
<td style="text-align: right;">Interval multiplier</td>
<td style="text-align: center;">k</td>
<td style="text-align: center;">2000</td>
<td
style="text-align: left;"><code>Device.LocalAgent.Controller.{i}.E2ESession.SessionRetryIntervalMultiplier</code></td>
</tr>
</tbody>
</table>
<table>
<colgroup>
<col style="width: 16%" />
<col style="width: 42%" />
<col style="width: 41%" />
</colgroup>
<thead>
<tr class="header">
<th style="text-align: right;">Retry Count</th>
<th style="text-align: center;">Default Wait Interval Range (min-max
seconds)</th>
<th style="text-align: left;">Actual Wait Interval Range (min-max
seconds)</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: right;">#1</td>
<td style="text-align: center;">5-10</td>
<td style="text-align: left;">m - m.(k/1000)</td>
</tr>
<tr class="even">
<td style="text-align: right;">#2</td>
<td style="text-align: center;">10-20</td>
<td style="text-align: left;">m.(k/1000) - m.(k/1000)^2</td>
</tr>
<tr class="odd">
<td style="text-align: right;">#3</td>
<td style="text-align: center;">20-40</td>
<td style="text-align: left;">m.(k/1000)^2 - m.(k/1000)^3</td>
</tr>
<tr class="even">
<td style="text-align: right;">#4</td>
<td style="text-align: center;">40-80</td>
<td style="text-align: left;">m.(k/1000)^3 - m.(k/1000)^4</td>
</tr>
<tr class="odd">
<td style="text-align: right;">#5</td>
<td style="text-align: center;">80-160</td>
<td style="text-align: left;">m.(k/1000)^4 - m.(k/1000)^5</td>
</tr>
<tr class="even">
<td style="text-align: right;">#6</td>
<td style="text-align: center;">160-320</td>
<td style="text-align: left;">m.(k/1000)^5 - m.(k/1000)^6</td>
</tr>
<tr class="odd">
<td style="text-align: right;">#7</td>
<td style="text-align: center;">320-640</td>
<td style="text-align: left;">m.(k/1000)^6 - m.(k/1000)^7</td>
</tr>
<tr class="even">
<td style="text-align: right;">#8</td>
<td style="text-align: center;">640-1280</td>
<td style="text-align: left;">m.(k/1000)^7 - m.(k/1000)^8</td>
</tr>
<tr class="odd">
<td style="text-align: right;">#9</td>
<td style="text-align: center;">1280-2560</td>
<td style="text-align: left;">m.(k/1000)^8 - m.(k/1000)^9</td>
</tr>
<tr class="even">
<td style="text-align: right;">#10 and subsequent</td>
<td style="text-align: center;">2560-5120</td>
<td style="text-align: left;">m.(k/1000)^9 - m.(k/1000)^10</td>
</tr>
</tbody>
</table>
<p><strong><span id="r-e2e.11"
class="auto-hoverlink">R-E2E.11</span></strong> - Beginning with the
tenth retry attempt, the Agent MUST choose from the fixed maximum range.
The Agent will continue to retry a failed session establishment until a
USP Message is successfully received by the Agent or until the
SessionExpiration time is reached.</p>
<p><strong><span id="r-e2e.12"
class="auto-hoverlink">R-E2E.12</span></strong> – Once a USP Record is
successfully received, the Agent MUST reset the Session Context retry
count to zero for the next Session Context establishment.</p>
<p><strong><span id="r-e2e.13"
class="auto-hoverlink">R-E2E.13</span></strong> – If a reboot of the
Agent occurs, the Agent MUST reset the Session Context retry count to
zero for the next Session Context establishment.</p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:usp-record-exchange">6.1.2 USP Record Exchange</h3>
<p>Once a Session Context is established, USP Records are created to
exchange payloads in the Session Context. USP Records are uniquely
identified by their originating USP Endpoint Identifier
(<code>from_id</code>), Session Context identifier
(<code>session_id</code>) and USP Record sequence identifier
(<code>sequence_id</code>).</p>
<h4 class="auto-hoverlink" data-info="header"
id="sec:usp-record-transmission">6.1.2.1 USP Record Transmission</h4>
<p>When an originating USP Endpoint transmits a USP Record, it creates
the USP Record with a monotonically increasing sequence identifier
(<code>sequence_id</code>).</p>
<p><strong><span id="r-e2e.14"
class="auto-hoverlink">R-E2E.14</span></strong> – When an originating
USP Endpoint transmits a USP Record, it MUST set the sequence identifier
of the first transmitted USP Record in the Session Context to 1.</p>
<p><strong><span id="r-e2e.15"
class="auto-hoverlink">R-E2E.15</span></strong> – When an originating
USP Endpoint transmits additional USP Records, the originating USP
Endpoint MUST monotonically increase the sequence identifier from the
last transmitted USP Record in the Session Context by one (1).</p>
<p>To communicate the sequence identifier of the last USP Record
received by a receiving USP Endpoint to the originating USP Endpoint,
whenever a USP Endpoint transmits a USP Record the originating USP
Endpoint communicates the next sequence identifier of a USP Record it
expects to receive in the <code>expected_id</code> field. The receiving
USP Endpoint uses this information to maintain its buffer of outgoing
(transmitted) USP Records such that any USP Records with a sequence
identifier less than the <code>expected_id</code> can be removed from
the receiving USP Endpoints buffer of transmitted USP Records for this
Session Context.</p>
<p><strong><span id="r-e2e.16"
class="auto-hoverlink">R-E2E.16</span></strong> – When an originating
USP Endpoint transmits a USP Record, the originating USP Endpoint MUST
preserve it in an outgoing buffer, for fulfilling retransmit requests,
until the originating USP Endpoint receives a USP Record from the
receiving USP Endpoint with a greater <code>expected_id</code>.</p>
<p><strong><span id="r-e2e.17"
class="auto-hoverlink">R-E2E.17</span></strong> – When an originating
USP Endpoint transmits a USP Record, the originating USP Endpoint MUST
inform the receiving USP Endpoint of the next sequence identifier in the
Session Context for a USP Record it expects to receive.</p>
<h4 class="auto-hoverlink" data-info="header"
id="sec:payload-security-within-the-session-context">6.1.2.2 Payload
Security within the Session Context</h4>
<p>The value of the <code>payload_security</code> field defines the type
of payload security that is performed in the Session Context. Once a
Session Context is established the payload security stays the same
throughout the lifetime of the Session Context.</p>
<p><strong><span id="r-e2e.18"
class="auto-hoverlink">R-E2E.18</span></strong> – The originating USP
Endpoint MUST use the same value in the <code>payload_security</code>
field for all USP Records within a Session Context.</p>
<h4 class="auto-hoverlink" data-info="header"
id="sec:usp-record-reception">6.1.2.3 USP Record Reception</h4>
<p>USP Records received by a USP Endpoint have information that is used
by the receiving USP Endpoint to process:</p>
<ol type="1">
<li>The payload contained within the USP Record,</li>
<li>A request to retransmit a USP Record, and</li>
<li>The contents of the outgoing buffer to clear the USP Records that
the originating USP Endpoint has indicated it has received from the
receiving USP Endpoint.</li>
</ol>
<p>As USP Records can be received out of order or not at all, the
receiving USP Endpoint only begins to process a USP Record when the
<code>sequence_id</code> field of the USP Record in the Session Context
is the <code>sequence_id</code> field that the receiving USP Endpoint
expects to receive. The following figure depicts the high-level
processing for USP Endpoints that receive a USP Record.</p>
<figure id="fig:processing-received-records">
<img src="e2e-message-exchange/processing-received-records.png"
id="img:processing-of-received-usp-records"
alt="Processing of Received USP Records" />
<figcaption><div class="auto-hoverlink"
data-anchor="fig:processing-received-records">
Figure 12: Processing of Received USP Records
</div></figcaption>
</figure>
<p><strong><span id="r-e2e.19"
class="auto-hoverlink">R-E2E.19</span></strong> – The receiving USP
Endpoint MUST ensure that the value in the <code>payload_security</code>
field for all USP Records within a Session Context is the same and fail
the USP Record if the value of the <code>payload_security</code> field
is different.</p>
<p><strong><span id="r-e2e.20"
class="auto-hoverlink">R-E2E.20</span></strong> – Incoming USP Records
MUST be processed per the following rules:</p>
<ol type="1">
<li>If the USP Record contains a <code>sequence_id</code> field larger
than the next <code>expected_id</code> value, the USP Record is added to
an incoming buffer of unprocessed USP Records.</li>
<li>If the <code>sequence_id</code> is less that the next
<code>expected_id</code>, the Endpoint MUST gracefully ignore the USP
Record.</li>
<li>If the <code>sequence_id</code> matches the
<code>expected_id</code>, for the USP Record and any sequential USP
Records in the incoming buffer:
<ol type="1">
<li>If the payload is not empty, it is passed to the implementation for
processing based on the type of payload in the
<code>payload_security</code> field and if the payload requires
reassembly according to the values of the <code>payload_sar_state</code>
and <code>payloadrec_sar_state</code> fields.</li>
<li>If a <code>retransmit_id</code> field is non-zero, the USP Record
with the sequence identifier of the <code>retransmit_id</code> field is
resent from the outgoing buffer.</li>
</ol></li>
<li>The <code>expected_id</code> field for new outgoing Records is set
to <code>sequence_id</code> field + 1 of this USP Record.</li>
</ol>
<h5 class="auto-hoverlink" data-info="header"
id="sec:failure-handling-of-received-usp-records-within-a-session-context">6.1.2.3.1
Failure Handling of Received USP Records Within a Session Context</h5>
<p>When a receiving USP Endpoint fails to either buffer or successfully
process a USP Record, the receiving USP Endpoint initiates a new Session
Context.</p>
<p><strong><span id="r-e2e.21"
class="auto-hoverlink">R-E2E.21</span></strong> – When a USP Endpoint
that receives a USP Record within a Session Context that fails to buffer
or successfully process (e.g., decode, decrypt, retransmit) the USP
Endpoint MUST start a new Session Context.</p>
<h4 class="auto-hoverlink" data-info="header"
id="sec:usp-record-retransmission">6.1.2.4 USP Record
Retransmission</h4>
<p>An Agent or Controller can request to receive USP Records that it
deems as missing at any time within the Session Context. The originating
USP Endpoint requests a USP Record from the receiving USP Endpoint by
placing the sequence identifier of the requested USP Record in the
<code>retransmit_id</code> field of the USP Record to be
transmitted.</p>
<p>The receiving USP Endpoint will determine if USP Record exists and
then re-send the USP Record to the originating USP Endpoint.</p>
<p>If the USP Record doesn’t exist, the USP Endpoint that received the
USP Record will consider the USP Record as failed and perform the
failure processing as defined in section Failure Handling of Received
USP Records.</p>
<p>To guard against excessive requests to retransmit a specific USP
Record, the USP Endpoint checks to see if the number of times the USP
Record has been retransmitted is greater than or equal to maximum times
a USP Record can be retransmitted as defined in the
<code>Device.LocalAgent.Controller.{i}.E2ESession.MaxRetransmitTries</code>
Parameter. If this condition is met, then the USP Endpoint that received
the USP Record with the retransmit request will consider the USP Record
as failed and perform the failure processing as defined in section
Failure Handling of Received USP Records.</p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:guidelines-for-handling-session-context-restarts">6.1.3
Guidelines for Handling Session Context Restarts</h3>
<p>A Session Context can be restarted for a number of reasons (e.g.,
sequence id exhaustion, errors, manual request). When a Session Context
is restarted, the USP Endpoints could have USP Records that have not
been transmitted, received or processed. This section provides guidance
for USP Endpoints when the Session Context is restarted.</p>
<p>The originating Endpoint is responsible for determining the policy
for recovering from USP Records that were not transmitted. For example,
the policy could be to resend the USP Message conveyed through the USP
Record, or to simply discard the USP Message.</p>
<p><strong><span id="r-e2e.22"
class="auto-hoverlink">R-E2E.22</span></strong> – The receiving USP
Endpoint MUST successfully process the USP Record through the
<code>expected_id</code> field that it last transmitted in the previous
session.</p>
<p>When a USP Endpoint receives a USP Record that cannot pass an
integrity check or that has an incorrect value in the
<code>session_id</code> field, the Session Context is restarted.</p>
<p><strong><span id="r-e2e.23"
class="auto-hoverlink">R-E2E.23</span></strong> – USP Records that do
not pass integrity checks MUST be silently ignored and the receiving USP
Endpoint MUST restart the Session Context.</p>
<p>This allows keys to be distributed and enabled under the old session
keys and then request a session restarted under the new keys.</p>
<p><strong><span id="r-e2e.24"
class="auto-hoverlink">R-E2E.24</span></strong> – USP Records that pass
the integrity check but have an invalid value in the
<code>session_id</code> field MUST be silently ignored and the receiving
USP Endpoint MUST restart the Session Context.</p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:segmented-message-exchange">6.1.4 Segmented Message
Exchange</h3>
<p>Since USP can use different types of MTPs, some MTPs place a
constraint on the size of the USP Record that it can transport. To
handle this, USP has a Segmentation and Reassembly function. When this
Segmentation and Reassembly function is performed by Controller and
Agent, it removes the possibly that the message may be blocked (and
typically) dropped by the intermediate transport servers. A Segmentation
and Reassembly example is shown in the figure below where the ACS
Controller segments the USP Message within the USP Record of 64K bytes
because the STOMP MTP Endpoint (in this example) can only handle frame
body up to 64K bytes.</p>
<p>While the <code>sequence_id</code> field identifies the USP Record
sequence identifier within the context of a Session Context and the
<code>retransmit_id</code> field provides a means of a receiving USP
Endpoint to indicate to the transmitting USP Endpoint that it needs a
specific USP Record to ensure information fields are processed in a
first-in-first-out (FIFO) manner, the Segmentation and Reassembly
function allows multiple payloads to be segmented by the transmitting
USP Endpoint and reassembled by the receiving USP Endpoint by augmenting
the USP Record with additional information fields without changing the
current semantics of the USP Record’s field definitions. This is done
using the <code>payload_sar_state</code> and
<code>payloadrec_sar_state</code> fields in the USP Record to indicate
status of the segmentation and reassembly procedure. This status along
with the existing <code>sequence_id</code>, <code>expected_id</code> and
<code>retransmit_id</code> fields and the foreknowledge of the maximum
allowed USP Record size (configurable by the
<code>Device.LocalAgent.Controller.{i}.E2ESession.MaxUSPRecordSize</code>
parameter) provide the information needed for two USP Endpoints to
perform segmentation and reassembly of payloads conveyed by USP Records.
In doing so, the constraint imposed by MTP Endpoints (that could be
intermediate MTP Endpoints) that do not have segmentation and reassembly
capabilities are alleviated. USP Messages of any size can now be
conveyed across any USP MTP Endpoint as depicted below:</p>
<figure id="fig:segmentation-and-reassembly">
<img src="e2e-message-exchange/segmentation-and-reassembly.png"
id="img:e2e-segmentation-and-reassembly"
alt="E2E Segmentation and Reassembly" />
<figcaption><div class="auto-hoverlink"
data-anchor="fig:segmentation-and-reassembly">
Figure 13: E2E Segmentation and Reassembly
</div></figcaption>
</figure>
<p><em>Note: the 64k size limit is not inherent to the STOMP protocol.
It is merely provided here as an example.</em></p>
<p><em>Note: for other protocols (e.g., MQTT), the maximum allowed size
by the MTP may also include its own header size, not only the conveyed
payload (e.g., MQTT packet size). In this case, the
<code>MaxUSPRecordSize</code> value must be a smaller value than the
maximal size of the MTP.</em></p>
<h4 class="auto-hoverlink" data-info="header"
id="sec:sar-function-algorithm">6.1.4.1 SAR function algorithm</h4>
<p>The following algorithm is used to provide the SAR function.</p>
<h5 class="auto-hoverlink" data-info="header"
id="sec:originating-usp-endpoint">6.1.4.1.1 Originating USP
Endpoint</h5>
<p>For each USP Message segment the Payload:</p>
<ol type="1">
<li>Compose the USP Message.</li>
<li>If <code>payload_security</code> is <code>TLS12</code>, encrypt the
USP Message. TLS will segment the encrypted Message per the maximum
allowed TLS record size.
<ol type="1">
<li>If all TLS records + Record header fields are less than the maximum
allowed USP Record size, then a single USP Record is sent.</li>
<li>Otherwise segmentation of the USP Record will need to be done.
<ol type="1">
<li>If the record size of a single TLS record + USP Record header fields
is less than the maximum allowed USP Record size, exactly one TLS record
can be included in a USP Record.</li>
<li>If the TLS record size + Record header fields is greater than the
maximum allowed USP Record size, the TLS record is segmented across
multiple USP Records.</li>
</ol></li>
</ol></li>
<li>If the Message is transmitted using <code>PLAINTEXT</code> and the
Message + Record header fields are greater than the maximum allowed USP
Record size, the USP Record is segmented.</li>
<li>Set the <code>payload_sar_state</code> field for each transmitted
Record.
<ol type="1">
<li>If there is only one Record, <code>payload_sar_state</code> =
<code>NONE (0)</code>.</li>
<li>If there is more than one USP Record, the
<code>payload_sar_state</code> field is set to <code>BEGIN (1)</code> on
the first Record, <code>COMPLETE (3)</code> on the last Record, and
<code>INPROCESS (2)</code> on all Records between the two.</li>
</ol></li>
<li>Set the <code>payloadrec_sar_state</code> field for each transmitted
Record.
<ol type="1">
<li>If there is only one Record or one Secure Message Exchange TLS
record per USP Record, <code>payloadrec_sar_state</code> =
<code>NONE (0)</code>.</li>
<li>If Secure Message Exchange TLS records or a <code>PLAINTEXT</code>
payload are segmented across multiple USP Records,
<code>payloadrec_sar_state</code> = <code>BEGIN (1)</code> on a Record
that contains the initial segment of a TLS record or
<code>PLAINTEXT</code> payload, <code>COMPLETE (3)</code> on a Record
that contains the final segment of a TLS record or
<code>PLAINTEXT</code> payload, and <code>INPROCESS (2)</code> on all
Records containing segments between initial and final segments of a TLS
record or <code>PLAINTEXT</code> payload.</li>
</ol></li>
<li>Each Record is sent (within a Session Context) using the procedures
defined in the USP Record Message Exchange section above.</li>
</ol>
<p>The effect of the above rules for <code>PLAINTEXT</code> payloads or
for Secure Message Exchange with a single TLS record is that
<code>payloadrec_sar_state</code> will be the same as
<code>payload_sar_state</code> for all Records used to communicate the
USP Message.</p>
<p><em>Note: The maximum allowed USP Record size can be exposed via the
data model using the
<code>Device.LocalAgent.Controller.{i}.E2ESession.MaxUSPRecordSize</code>
Parameter.</em></p>
<h5 class="auto-hoverlink" data-info="header"
id="sec:receiving-endpoint">6.1.4.1.2 Receiving Endpoint</h5>
<p>For each USP Message reassemble the segmented payload:</p>
<ol type="1">
<li>When a USP Record that indicates segmentation has started, store the
USP Records until a USP Record is indicated to be complete. A completed
segmentation is where the USP Record’s <code>payload_sar_state</code>
and <code>payloadrec_sar_state</code> have a value of
<code>COMPLETE (3)</code>.</li>
<li>Follow the procedures in USP Record Retransmission to retransmit any
USP Records that were not received.</li>
<li>Once the USP Record is received that indicates that the segmentation
is complete, reassemble the payload by appending the payloads using the
monotonically increasing <code>sequence_id</code> field’s value from the
smaller number to larger sequence numbers. The reassembly keeps the
integrity of the instances of the payload field’s payload records. To
keep the integrity of the payload record, the payload record is
reassembled using the <code>payloadrec_sar_state</code> values.</li>
<li>Reassembly of the payload that represents the USP Message is
complete.</li>
</ol>
<p>If the segmentation and reassembly fails for any reason, the USP
Endpoint that received the segmented USP Records will consider the last
received USP Record as failed and perform the failure processing as
defined in section Failure Handling of Received USP Records.</p>
<h4 class="auto-hoverlink" data-info="header"
id="sec:segmentation-examples">6.1.4.2 Segmentation Examples</h4>
<p>The following examples show the values assigned to
<code>payload_sar_state</code> and <code>payloadrec_sar_state</code>
fields for various permutations of <code>payload_security</code>, and
maximum USP Record size and Secure Message Exchange maximum TLS record
size relative to the size of the USP Message. The examples are not
exhaustive.</p>
<p><strong>Case 1: payload_security = PLAINTEXT, single USP
Record</strong></p>
<p>Conditions:</p>
<ol type="1">
<li>Maximum USP Record size &gt; size of (USP Message + USP Record
header)</li>
</ol>
<p><img src="e2e-message-exchange/segmentation-case-1.png" /></p>
<p><strong>Case 2: payload_security = PLAINTEXT, fragmented across
multiple USP Records</strong></p>
<p>Conditions:</p>
<ol type="1">
<li>Maximum USP Record size &lt; size of (USP Message + USP Record
header)</li>
</ol>
<p><img src="e2e-message-exchange/segmentation-case-2.png" /></p>
<p><strong>Case 3: payload_security = TLS12, single TLS record, single
USP Record</strong></p>
<p>Conditions:</p>
<ol type="1">
<li>Maximum TLS record size &gt; size of (USP Message + TLS record
header)</li>
<li>Maximum USP Record size &gt; size of USP Message + size of TLS
record header + size of USP Record header</li>
</ol>
<p><img src="e2e-message-exchange/segmentation-case-3.png" /></p>
<p><strong>Case 4: Payload_security = TLS12, all TLS records in a single
USP Record</strong></p>
<p>Conditions:</p>
<ol type="1">
<li>Maximum TLS record size &lt; size of (USP Message + TLS record
header)</li>
<li>Maximum USP Record size &gt; size of all TLS records + size of USP
Record header</li>
</ol>
<p><img src="e2e-message-exchange/segmentation-case-4.png" /></p>
<p><strong>Case 5: Payload_security = TLS12, single TLS record
fragmented across multiple USP Records</strong></p>
<p>Conditions:</p>
<ol type="1">
<li>Maximum TLS record size &gt; size of (USP Message + TLS record
header)</li>
<li>Maximum USP Record size &lt; size of (TLS record + USP Record
header)</li>
</ol>
<p><img src="e2e-message-exchange/segmentation-case-5.png" /></p>
<p><strong>Case 6: Payload_security = TLS12, multiple TLS records, one
TLS record per USP Record</strong></p>
<p>Conditions:</p>
<ol type="1">
<li>Maximum TLS record size &lt; size of (USP Message + TLS record
header)</li>
<li>Maximum USP Record size &gt; maximum TLS record size + size of USP
Record header</li>
<li>Maximum USP Record size &lt; size of USP Message + size of TLS
record header + size of USP Record header</li>
</ol>
<p><img src="e2e-message-exchange/segmentation-case-6.png" /></p>
<p><strong>Case 7: Payload_security = TLS12, multiple TLS records, some
TLS records fragmented across multiple USP Records</strong></p>
<p>Conditions:</p>
<ol type="1">
<li>Maximum TLS record size &lt; size of (USP Message + TLS record
header)</li>
<li>Maximum USP Record size &lt; size of (some TLS records + USP Record
header)</li>
</ol>
<p><img src="e2e-message-exchange/segmentation-case-7.png" /></p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:handling-duplicate-usp-records">6.1.5 Handling Duplicate USP
Records</h3>
<p>Circumstances may arise (such as multiple Message Transfer Protocols,
retransmission requests) that cause duplicate USP Records (those with an
identical <code>sequence_id</code> and <code>session_id</code> fields
from the same USP Endpoint) to arrive at the target USP Endpoint.</p>
<p><strong><span id="r-e2e.25"
class="auto-hoverlink">R-E2E.25</span></strong> - When exchanging USP
Records with an E2E Session Context, if a target USP Endpoint receives a
USP Record with duplicate <code>sequence_id</code> and
<code>session_id</code> fields from the same originating USP Endpoint,
it MUST gracefully ignore the duplicate USP Record.</p>
<h2 class="auto-hoverlink" data-info="header"
id="sec:exchange-of-usp-records-without-an-e2e-session-context">6.2
Exchange of USP Records without an E2E Session Context</h2>
<p>When the exchange of USP Records without an E2E Session Context is
used, the <code>record_type</code> is set to
<code>no_session_context</code>.</p>
<p>When a USP Record that is received without an E2E Session Context
contains a USP Message request, its associated response or error message
is sent without an E2E Session Context, unless otherwise specified (see
<a href="#sec:requests-responses-and-errors" class="heading">Requests,
Responses and Errors</a>).</p>
<p><strong><span id="r-e2e.26"
class="auto-hoverlink">R-E2E.26</span></strong> - A
<code>record_type</code> of <code>no_session_context</code> MUST be used
for exchange of USP Records without an E2E Session Context. A non-zero
<code>payload</code> MUST be included.</p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:failure-handling-of-received-usp-records-without-a-session-context">6.2.1
Failure Handling of Received USP Records Without a Session Context</h3>
<p>When a receiving USP Endpoint fails to either buffer or successfully
process a USP Record, the receiving USP Endpoint reports a failure.</p>
<p><strong><span id="r-e2e.27"
class="auto-hoverlink">R-E2E.27</span></strong> (DEPRECATED) - When a
USP Endpoint that receives a USP Record without a Session Context that
fails to buffer or successfully process (e.g., decode, decrypt,
retransmit) the USP Endpoint SHOULD send a <code>DisconnectRecord</code>
(as described in <a href="#r-mtp.7" class="requirement">R-MTP.7</a> for
Agents).</p>
<p><em>Note: Requirement <a href="#r-e2e.27"
class="requirement">R-E2E.27</a> was removed in USP 1.3, replaced by the
behavior defined in <a href="#r-mtp.5"
class="requirement">R-MTP.5</a></em></p>
<p>Note that <a href="#r-mtp.7" class="requirement">R-MTP.7</a> says
Agents should send a <code>DisconnectRecord</code> when terminating an
MTP. Controllers can also send a <code>DisconnectRecord</code> in this
case. The MTP can stay connected. Brokered MTP sessions are expected to
remain but other MTP connections could be closed.</p>
<h2 class="auto-hoverlink" data-info="header"
id="sec:validating-the-integrity-of-the-usp-record">6.3 Validating the
Integrity of the USP Record</h2>
<p>When a USP Record is transmitted to a USP Endpoint, the transmitting
USP Endpoint has the capability to protect the integrity of the
non-payload fields of the USP Record. The <code>payload</code> field is
not part of the generation or verification process, as the expectation
is that this element will be secured using an E2E security protection
mechanism (<code>payload_security</code> other than PLAINTEXT).</p>
<p>The integrity of the USP Record is required to be validated when the
USP Record cannot be protected by the underlying MTP.</p>
<p><strong><span id="r-e2e.28"
class="auto-hoverlink">R-E2E.28</span></strong> - When a USP Record is
received or transmitted the following conditions MUST apply for the USP
Record to be considered protected by the underlying MTP:</p>
<ul>
<li>The MTP is encrypted per requirements in the applicable MTP
section</li>
<li>The peer MTP certificate contains an Endpoint ID and this Endpoint
ID is the same as the USP Record <code>from_id</code> field OR the peer
MTP certificate is directly associated (e.g., referenced from a
<code>Device.LocalAgent.Controller.{i}.Credential</code> Parameter) with
a Controller whose Endpoint ID matches the USP Record
<code>from_id</code> field.</li>
<li>The peer MTP certificate is that of a Trusted Broker.</li>
</ul>
<p><strong><span id="r-e2e.29"
class="auto-hoverlink">R-E2E.29</span></strong> – Unless protected by
the underlying MTP, when a USP Endpoint transmits a USP Record, the USP
Endpoint MUST protect the integrity of the non-payload portion of the
USP Record.</p>
<p><strong><span id="r-e2e.30"
class="auto-hoverlink">R-E2E.30</span></strong> – When a USP Endpoint
receives a USP Record, the USP Endpoint MUST verify the integrity of the
non-payload portion of the USP Record when the USP Record contains the
mac_signature field or the USP Endpoint is not protected by the
underlying MTP.</p>
<p>The integrity of the non-payload fields is accomplished by the
transmitting USP Endpoint generating a Message Authentication Code (MAC)
or signature of the non-payload fields which is then placed into the
mac_signature field where the receiving USP Endpoint then verifies the
MAC or signature as appropriate. The method to generate and validate MAC
or signature depends on the value of the <code>payload_security</code>
field. If the value of the <code>payload_security</code> field is
<code>PLAINTEXT</code> then the integrity validation method always uses
the signature method described in section Using the Signature Method to
Validate the Integrity of USP Records. If the value of the
<code>payload_security</code> field is <code>TLS12</code> then the
validation method that is used is dependent on whether the TLS handshake
has been completed. If the TLS handshake has not been completed, the
signature method described in section Using the Signature Method to
Validate the Integrity of USP Records is used otherwise the MAC method
described in section Using TLS to Validate the Integrity of USP Records
is used.</p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:using-the-signature-method-to-validate-the-integrity-of-usp-records">6.3.1
Using the Signature Method to Validate the Integrity of USP Records</h3>
<p>When the transmitting USP Endpoint protects the integrity of the
non-payload fields of the USP Record using the signature method in this
section, the non-payload fields are protected by signing a hash of the
non-payload fields using the private key of the sending USP Endpoint’s
certificate. The receiving USP Endpoint then verifies the integrity
using either the public key of the certificate in the USP Record
<code>sender_cert</code> field or of the certificate used for Secure
Message Exchange.</p>
<p>This signature method uses the SHA-256 hash algorithm, as defined in
FIPS PUB 180-4 Secure Hash Standard (SHS) <span class="citation"
data-cites="FIPS-180.4"><a href="#ref-FIPS-180.4"
role="doc-biblioref">[25]</a></span>, and the NIST P-256 curve that
generates a signature for the hash using the Digital Signature Standard
(DSS) scheme as defined in FIPS PUB 186-4 Digital Signature Standard
(DSS) <span class="citation" data-cites="FIPS-186.4"><a
href="#ref-FIPS-186.4" role="doc-biblioref">[26]</a></span>. To reduce
the burden of requiring a strong source of randomness, the signature
algorithm may apply the method described in RFC 6979 <span
class="citation" data-cites="RFC6979"><a href="#ref-RFC6979"
role="doc-biblioref">[23]</a></span> to deterministically derive
encryption parameters. The signature must be ASN.1 DER-encoded as
described in RFC 3279 <span class="citation" data-cites="RFC3279"><a
href="#ref-RFC3279" role="doc-biblioref">[12]</a></span>, we will refer
to this signature scheme as <code>ECDSA_P256_SHA256_ASN1</code> in this
specification.</p>
<p><strong><span id="r-e2e.31"
class="auto-hoverlink">R-E2E.31</span></strong> – When using the
signature method to protect the integrity of the non-payload portion of
the USP Record, the transmitting USP Endpoint MUST protect the integrity
using the <code>ECDSA_P256_SHA256_ASN1</code> signature scheme, as
defined in this specification, to sign and verify the protection. The
transmitting USP Endpoint MUST create the signature using the private
key of the transmitting USP Endpoint’s certificate. The receiving USP
Endpoint MUST verify the signature using the public key of the
transmitted sender’s certificate.</p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:using-tls-to-validate-the-integrity-of-usp-records">6.3.2 Using
TLS to Validate the Integrity of USP Records</h3>
<p>When the transmitting and receiving USP Endpoints have established a
TLS session, the transmitting USP Endpoint no longer needs to generate a
signature or transmit the sender’s certificate with the USP Record.
Instead the transmitting USP Endpoint generates a MAC that is verified
by the receiving USP Endpoint. The MAC ensures the integrity of the
non-payload fields of the USP Record. The MAC mechanism used in USP for
this purpose is the SHA-256 keyed-Hash Message Authentication Code
(HMAC) algorithm. The keys used for the HMAC algorithm are derived in
accordance with RFC 5705 <span class="citation" data-cites="RFC5705"><a
href="#ref-RFC5705" role="doc-biblioref">[16]</a></span> when using TLS
1.2 or in accordance with the updated version found in RFC 8446 <span
class="citation" data-cites="RFC8446"><a href="#ref-RFC8446"
role="doc-biblioref">[24]</a></span> when using TLS 1.3. These
procedures require the following inputs: a label, a context and the
length of the output keying material. The label used must be
“<code>EXPORTER-BBF-USP-Record</code>”, the context must be empty (note
that, for TLS 1.2, an empty context, i.e. zero length, is different than
no context at all) and the output length must be 64 octets, where the
first 32 octets will be used as the client key and the other 32 octets
as the server key (in TLS terms). When using TLS 1.2, the PRF used must
be the one defined in RFC 5246 <span class="citation"
data-cites="RFC5246"><a href="#ref-RFC5246"
role="doc-biblioref">[33]</a></span> with SHA-256 Hash.</p>
<p><strong><span id="r-e2e.32"
class="auto-hoverlink">R-E2E.32</span></strong> – When generating or
validating the MAC or signature to protect the integrity of the USP
Record, the sequence of the non-payload fields MUST use the field
identifier of the USP Record’s protobuf specification proceeding from
lowest to highest. The non-payload fields in the Record definition
(other than the <code>mac_signature</code> field itself) MUST be used
first and then the fields of the <code>SessionContextRecord</code> if
applicable.</p>
<p><strong><span id="r-e2e.32-1"
class="auto-hoverlink">R-E2E.32</span>.1</strong> – When generating or
validating the MAC or signature, all non-payload fields MUST be appended
as byte arrays and fed into the MAC or signature generation function
with the following conditions:</p>
<ul>
<li>uint64 types MUST be passed as 8 bytes in big endian ordering</li>
<li>uint32 types MUST be passed as 4 bytes in big endian ordering</li>
<li>enum types MUST be treated as uint32</li>
<li>string types MUST be passed as UTF-8 encoded byte array</li>
<li>bytes types MUST be passed as is</li>
</ul>
<p><strong><span id="r-e2e.33"
class="auto-hoverlink">R-E2E.33</span></strong> – If using the TLS MAC
method to protect the integrity of a USP Record, and a USP Endpoint
receives a USP Record, the USP Endpoint MUST verify the MAC using the
SHA-256 HMAC algorithm for the non-payload portion of the USP
Record.</p>
<p><strong><span id="r-e2e.34"
class="auto-hoverlink">R-E2E.34</span></strong> – If using the TLS MAC
method to protect the integrity of a USP Record, when generating or
validating the MAC of the USP Record, the sequence of the non-payload
fields MUST use the field identifier of the USP Record’s protobuf
specification proceeding from lowest to highest.</p>
<p><strong><span id="r-e2e.35"
class="auto-hoverlink">R-E2E.35</span></strong> – If using the TLS MAC
method to protect the integrity of a USP Record, when generating or
validating the MAC of the USP Record, the USP Endpoint MUST derive the
keys in accordance with RFC 5705 <span class="citation"
data-cites="RFC5705"><a href="#ref-RFC5705"
role="doc-biblioref">[16]</a></span> when using TLS 1.2 or with
accordance with RFC 8446 <span class="citation" data-cites="RFC8446"><a
href="#ref-RFC8446" role="doc-biblioref">[24]</a></span> when using TLS
1.3.</p>
<p><strong><span id="r-e2e.36"
class="auto-hoverlink">R-E2E.36</span></strong> – If using the TLS MAC
method to protect the integrity of a USP Record, when generating or
validating the MAC of the USP Record, the USP Endpoint MUST use a label
value of “<code>EXPORTER-BBF-USP-Record</code>” and a zero length
context.</p>
<p><strong><span id="r-e2e.37"
class="auto-hoverlink">R-E2E.37</span></strong> – If using the TLS MAC
method to protect the integrity of a USP Record, when generating or
validating the MAC of the USP Record, the USP Endpoint MUST generate 64
octets of keying material.</p>
<p><strong><span id="r-e2e.38"
class="auto-hoverlink">R-E2E.38</span></strong> – If using the TLS MAC
method to protect the integrity of a USP Record, when generating or
validating the MAC of the USP Record, the USP Endpoint MUST use the TLS
PRF defined in RFC 5246 <span class="citation" data-cites="RFC5246"><a
href="#ref-RFC5246" role="doc-biblioref">[33]</a></span> with SHA-256
Hash when using TLS 1.2 for End-to-End security.</p>
<p><strong><span id="r-e2e.39"
class="auto-hoverlink">R-E2E.39</span></strong> – If using the TLS MAC
method to protect the integrity of a USP Record, when generating the MAC
of the USP Record, the USP Endpoint MUST use the first 32 octets of the
keying material as the client key and the other 32 octets as the server
key.</p>
<h2 class="auto-hoverlink" data-info="header"
id="sec:secure-message-exchange">6.4 Secure Message Exchange</h2>
<p>While message transport bindings implement point-to-point security,
the existence of broker-based message transports and transport proxies
creates a need for end-to-end security within the USP protocol.
End-to-end security is established by securing the payloads prior to
segmentation and transmission by the originating USP Endpoint and the
decryption of reassembled payloads by the receiving USP Endpoint. The
indication whether and how the USP Message has been secured is via the
<code>payload_security</code> field. This field defines the security
protocol or mechanism applied to the USP payload, if any. This section
describes the payload security protocols supported by USP.</p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:tls-payload-encapsulation">6.4.1 TLS Payload Encapsulation</h3>
<p>USP employs TLS as one security mechanism for protection of USP
payloads in Agent-Controller message exchanges.</p>
<p>While traditionally deployed over reliable streams, TLS is a
record-based protocol that can be carried over datagrams, with
considerations taken for reliable and in-order delivery. To aid
interoperability, USP Endpoints are initially limited to a single cipher
specification, though future revisions of the protocol may choose to
expand cipher support.</p>
<p><strong><span id="r-e2e.40"
class="auto-hoverlink">R-E2E.40</span></strong> – When using TLS to
protect USP payloads in USP Records, USP Endpoints MUST implement TLS
1.2 or later (with backward compatibility to TLS 1.2) with the
<code>ECDHE-ECDSA-AES128-GCM-SHA256</code> cipher for TLS 1.2 and the
<code>TLS-AES128-GCM-SHA256</code> cipher for TLS 1.3.</p>
<p><strong><span id="r-e2e.40a"
class="auto-hoverlink">R-E2E.40a</span></strong> - When using TLS to
protect USP payloads in USP Records, USP Endpoints MUST use ECDHE for
key exchange and MUST support the named group <code>secp256r1</code>
(NIST P-256 curve) for use in ECDHE.</p>
<p><strong><span id="r-e2e.40b"
class="auto-hoverlink">R-E2E.40b</span></strong> - When using TLS to
protect USP payloads in USP Records, USP Endpoints MUST use the ECDSA
signature scheme with the NIST P-256 curve and SHA-256.</p>
<p><em>Note: The requirements listed above require a USP Endpoint to use
X.509 certificates with an Elliptic-curve public key compatible with the
NIST P-256 curve.</em></p>
<h4 class="auto-hoverlink" data-info="header"
id="sec:session-handshake">6.4.1.1 Session Handshake</h4>
<p>When TLS is used as a payload protection mechanism for USP Message,
TLS requires the use of the Session Context to negotiate its TLS
session. The USP Endpoint that initiated the Session Context will act in
the TLS client role when establishing the security layer. The security
layer is constructed using a standard TLS handshake, encapsulated within
one or more of the above-defined USP Record payload datagrams. Per the
TLS protocol, establishment of a new TLS session requires two
round-trips.</p>
<figure id="fig:handshake">
<img src="e2e-message-exchange/tls-session-handshake.png"
id="img:tls-session-handshake" alt="TLS Session Handshake" />
<figcaption><div class="auto-hoverlink" data-anchor="fig:handshake">
Figure 14: TLS Session Handshake
</div></figcaption>
</figure>
<p><strong><span id="r-e2e.41"
class="auto-hoverlink">R-E2E.41</span></strong> – USP Endpoints that
specify <code>TLS12</code> in the <code>payload_security</code> field
MUST exchange USP Records within an E2E Session Context.</p>
<p>If the TLS session cannot be established for any reason, the USP
Endpoint that received the USP Record will consider the USP Record as
failed and perform the failure processing as defined in section Failure
Handling of Received USP Records.</p>
<p>TLS provides a mechanism to renegotiate the keys of a TLS session
without tearing down the existing session called TLS renegotiation.
However, for E2E Message exchange in USP, TLS renegotiation is
forbidden.</p>
<p><strong><span id="r-e2e.42"
class="auto-hoverlink">R-E2E.42</span></strong> – USP Endpoints MUST NOT
accept requests for TLS renegotiation when used for E2E Message
exchange. USP Endpoints MAY send a TLS <code>no_renegotiation</code>
alert in response to a request for renegotiation.</p>
<h4 class="auto-hoverlink" data-info="header"
id="sec:authentication">6.4.1.2 Authentication</h4>
<p>USP relies upon peer authentication using X.509 certificates, as
provided by TLS. Each USP Endpoint identifier is identified within an
X.509 certificate. The rules for authentication are provided in <a
href="#sec:auth" class="heading">Authentication and
Authorization</a>.</p>
<p><strong><span id="r-e2e.43"
class="auto-hoverlink">R-E2E.43</span></strong> – USP Endpoints MUST be
mutually authenticated using X.509 certificates.</p>
<p>Agents will authenticate Controllers according to rules for analysis
of Controller certificates requirements in <a
href="#sec:analysis-controller-certificates" class="heading">Analysis of
Controller Certificates</a>. Controllers will authenticate Agents using
the USP Endpoint identifier encoded in the Agent’s certificate as per <a
href="#sec:agent-authentication" class="heading">Agent
Authentication</a></p>
<h1 class="auto-hoverlink" data-info="header" id="sec:messages">7
Messages</h1>
<p>USP contains messages to create, read, update, and delete Objects,
perform Object-defined operations, and allow Agents to notify
controllers of events. This is often referred to as CRUD with the
addition of O (operate) and N (notify), or CRUD-ON.</p>
<p><em>Note: This version of the specification defines its Messages in
<a href="#sec:encoding" class="heading">Protocol Buffers v3</a>. This
part of the specification may change to a more generic description
(normative and non-normative) if further encodings are specified in
future versions.</em></p>
<p>These sections describe the types of USP Messages and the normative
requirements for their flow and operation. USP Messages are described in
a protocol buffers schema, and the normative requirements for the
individual fields of the schema are outlined below.</p>
<h2 class="auto-hoverlink" data-info="header"
id="sec:encapsulation-in-a-usp-record">7.1 Encapsulation in a USP
Record</h2>
<p>All USP Messages are encapsulated by a USP Record. The definition of
the USP Record portion of a USP Message can be found in <a
href="#sec:record-definition" class="heading">Record Definition</a>, and
the rules for managing transactional integrity are described in <a
href="#sec:e2e-message-exchange" class="heading">End to End Message
Exchange</a>.</p>
<h2 class="auto-hoverlink" data-info="header"
id="sec:requests-responses-and-errors">7.2 Requests, Responses and
Errors</h2>
<p>The three types of USP Messages are Request, Response, and Error.</p>
<p>A request is a Message sent from a source USP Endpoint to a target
USP Endpoint that includes fields to be processed and returns a response
or error. Unless otherwise specified, all requests have an associated
response. Though the majority of requests are made from a Controller to
an Agent, the Notify and Register Messages follow the same format as a
request but is sent from an Agent to a Controller.</p>
<p><strong><span id="r-msg.0"
class="auto-hoverlink">R-MSG.0</span></strong> - The target USP Endpoint
MUST respond to a request Message from the source USP Endpoint with
either a response Message or Error Message, unless otherwise specified
(see <a href="#sec:operate" class="heading">The Operate Message</a> and
<a href="#sec:notify" class="heading">The Notify Message</a>).</p>
<p><strong><span id="r-msg.0a"
class="auto-hoverlink">R-MSG.0a</span></strong> - The associated
response or error Message MUST be sent through the same type of USP
Record (i.e. A <code>record_type</code> of <a
href="#sec:exchange-of-usp-records-within-an-e2e-session-context"
class="heading"><code>session_context</code></a> or <a
href="#sec:exchange-of-usp-records-without-an-e2e-session-context"
class="heading"><code>no_session_context</code></a>) used along the
associated request Message.</p>
<p><strong><span id="r-msg.1"
class="auto-hoverlink">R-MSG.1</span></strong> - The target USP Endpoint
MUST ignore or send an Error Message in response to Messages it does not
understand.</p>
<p><em>Note: Requirement R-MSG.2 was removed in USP 1.2, because it did
not align with the concept of brokered MTPs and long-lived connections
in general.</em></p>
<p><strong><span id="r-msg.3"
class="auto-hoverlink">R-MSG.3</span></strong> - In any USP Message
originating from an Agent, unless otherwise specified, Path Names
reported from the Agent’s Instantiated Data Model MUST use Instance
Number Addressing.</p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:handling-duplicate-messages">7.2.1 Handling Duplicate
Messages</h3>
<p>Circumstances may arise (such as multiple Message Transfer Protocols)
that cause duplicate Messages (those with an identical Message ID) to
arrive at the target USP Endpoint.</p>
<p><strong><span id="r-msg.4"
class="auto-hoverlink">R-MSG.4</span></strong> - If a target USP
Endpoint receives a Message with a duplicate Message ID before it has
processed and sent a Response or Error to the original Message, it MUST
gracefully ignore the duplicate Message.</p>
<p>For Messages that require no response, it is up to the target
Endpoint implementation when to allow the same Message ID to be re-used
by the same source USP Endpoint.</p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:handling-search-expressions">7.2.2 Handling Search
Expressions</h3>
<p>Many USP Messages allow for search expressions to be used in the
request. To help make Controller requests more flexible, it is desired
that requests using search expressions that match zero Objects should
receive a successful response. In these cases, the Agent is in the
desired state the Controller intends, and the result should not
interrupt the Controller’s application.</p>
<p>In the Messages below, this requirement is sometimes explicit, but it
is stated here as a general requirement.</p>
<p><strong><span id="r-msg.4a"
class="auto-hoverlink">R-MSG.4a</span></strong> - Unless otherwise
specified, if a Request contains a Search Path, the associated Response
MUST result in a successful operation with an empty element
(i.e. <code>oper_success{}</code>) if the Search Path matches zero
Objects in the Agent’s Instantiated Data Model.</p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:example-message-flows">7.2.3 Example Message Flows</h3>
<p>Successful request/response: In this successful Message sequence, a
Controller sends an Agent a request. The Message header and body are
parsed, the Message is understood, and the Agent sends a response with
the relevant information in the body.</p>
<p><em>Note: this is not meant to imply that all request/response
operations will be synchronous. Controllers can and should expect that
Responses may be received in a different order than that in which
Requests were made.</em></p>
<figure id="fig:a-successful-requestresponse-sequence">
<img src="messages/successful_response.png"
id="img:a-successful-requestresponse-sequence"
alt="A successful request/response sequence" />
<figcaption><div class="auto-hoverlink"
data-anchor="fig:a-successful-requestresponse-sequence">
Figure 15: A successful request/response sequence
</div></figcaption>
</figure>
<p>Failed request/response: In this failed Message sequence, a
Controller sends an Agent a request. The Message header and body are
parsed, but the Agent throws an error. The error arguments are generated
and sent in an Error Message.</p>
<figure id="fig:a-failed-requestresponse-sequence">
<img src="messages/error_response.png"
id="img:a-failed-requestresponse-sequence"
alt="A failed request/response sequence" />
<figcaption><div class="auto-hoverlink"
data-anchor="fig:a-failed-requestresponse-sequence">
Figure 16: A failed request/response sequence
</div></figcaption>
</figure>
<h2 class="auto-hoverlink" data-info="header"
id="sec:message-structure">7.3 Message Structure</h2>
<p>A Message consists of a header and body. When using Protocol Buffers
<span class="citation" data-cites="PROTOBUF"><a href="#ref-PROTOBUF"
role="doc-biblioref">[4]</a></span>, the fields of the header and body
for different Messages are defined in a schema and sent in an encoded
format from one USP Endpoint to another.</p>
<p><strong><span id="r-msg.5"
class="auto-hoverlink">R-MSG.5</span></strong> - A Message MUST conform
to the schemas defined in <a
href="../specification/usp-msg-1-3.proto">usp-msg-1-3.proto</a>.</p>
<p><em>See the section on <a href="#sec:usp-record-encapsulation"
class="heading">USP Record Encapsulation</a> for information about
Protocol Buffers default behavior and required fields.</em></p>
<p>Every USP Message contains a header and a body. The header contains
basic destination and coordination information, and is separated to
allow security and discovery mechanisms to operate. The body contains
the message itself and its arguments.</p>
<p>Each of the Message types and fields below are described with the
field type according to Protocol Buffers <span class="citation"
data-cites="PROTOBUF"><a href="#ref-PROTOBUF"
role="doc-biblioref">[4]</a></span>, followed by its name.</p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:the-usp-message">7.3.1 The USP Message</h3>
<p><code>Header header</code></p>
<p><strong><span id="r-msg.6"
class="auto-hoverlink">R-MSG.6</span></strong> - A Message MUST contain
exactly one header field.</p>
<p><code>Body body</code></p>
<p>The Message Body that must be present in every Message. The Body
field contains either a Request, Response, or Error field.</p>
<p><strong><span id="r-msg.7"
class="auto-hoverlink">R-MSG.7</span></strong> - A Message MUST contain
exactly one body field.</p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:message-header">7.3.2 Message Header</h3>
<p>The Message Header includes a Message ID to associate Requests with
Responses or Errors, and a field indicating the type of Message.</p>
<p>The purpose of the Message Header is to provide basic information
necessary for the target Endpoint to process the message.</p>
<h4 class="auto-hoverlink" data-info="header"
id="sec:message-header-fields">7.3.2.1 Message Header Fields</h4>
<p><code>string msg_id</code></p>
<p>A locally unique opaque identifier assigned by the Endpoint that
generated this Message.</p>
<p><strong><span id="r-msg.8"
class="auto-hoverlink">R-MSG.8</span></strong> - The msg_id field MUST
be present in every Header.</p>
<p><strong><span id="r-msg.9"
class="auto-hoverlink">R-MSG.9</span></strong> - The msg_id field in the
Message Header for a Response or Error that is associated with a Request
MUST contain the Message ID of the associated request. If the msg_id
field in the Response or Error does not contain the Message ID of the
associated Request, the response or error MUST be ignored.</p>
<p><code>enum MsgType msg_type</code></p>
<p>This field contains an enumeration indicating the type of message
contained in the Message body. It is an enumeration of:</p>
<pre><code>    ERROR (0)
    GET (1)
    GET_RESP (2)
    NOTIFY (3)
    SET (4)
    SET_RESP (5)
    OPERATE (6)
    OPERATE_RESP (7)
    ADD (8)
    ADD_RESP (9)
    DELETE (10)
    DELETE_RESP (11)
    GET_SUPPORTED_DM (12)
    GET_SUPPORTED_DM_RESP (13)
    GET_INSTANCES (14)
    GET_INSTANCES_RESP (15)
    NOTIFY_RESP (16)
    GET_SUPPORTED_PROTO (17)
    GET_SUPPORTED_PROTO_RESP (18)
    REGISTER (19)
    REGISTER_RESP (20)
    DEREGISTER (21)
    DEREGISTER_RESP (22)</code></pre>
<p><strong><span id="r-msg.10"
class="auto-hoverlink">R-MSG.10</span></strong> - The
<code>msg_type</code> field MUST be present in every Header. Though
required, it is meant for information only. In the event this field
differs from the <code>req_type</code> or <code>resp_type</code> in the
Message body (respectively), the type given in either of those elements
SHOULD be regarded as correct.</p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:message-body">7.3.3 Message Body</h3>
<p>The Message body contains the intended message and the appropriate
fields for the Message type.</p>
<p>Every Message body contains exactly one message and its fields. When
an Agent is the target Endpoint, these messages can be used to create,
read, update, and delete Objects, or execute Object-defined operations.
When a Controller is the target Endpoint, the Message will contain a
notification, response, or an error.</p>
<h4 class="auto-hoverlink" data-info="header"
id="sec:message-body-fields">7.3.3.1 Message Body Fields</h4>
<p><code>oneof msg_body</code></p>
<p>This field contains one of the types given below:</p>
<p><code>Request request</code></p>
<p>This field indicates that the Message contains a request of a type
given in the Request Message.</p>
<p><code>Response response</code></p>
<p>This field indicates that the Message contains a response of a type
given in the Response Message.</p>
<p><code>Error  error</code></p>
<p>This field indicates that the Message contains an Error Message.</p>
<h4 class="auto-hoverlink" data-info="header"
id="sec:request-fields">7.3.3.2 Request Fields</h4>
<p><code>oneof req_type</code></p>
<p>This field contains one of the types given below. Each indicates that
the Message contains a Message of the given type.</p>
<pre><code>    Get get
    GetSupportedDM get_supported_dm
    GetInstances get_instances
    Set set
    Add add
    Delete delete
    Operate operate
    Notify notify
    GetSupportedProtocol get_supported_protocol
    Register register
    Deregister deregister</code></pre>
<h4 class="auto-hoverlink" data-info="header"
id="sec:response-fields">7.3.3.3 Response Fields</h4>
<p><code>oneof resp_type</code></p>
<p>This field contains one of the types given below. Each indicates that
the Message contains a Message of the given type.</p>
<pre><code>    GetResp get_resp
    GetSupportedDMResp get_supported_dm_resp
    GetInstancesResp get_instances_resp
    SetResp set_resp
    AddResp add_resp
    DeleteResp delete_resp
    OperateResp operate_resp
    NotifyResp notify_resp
    GetSupportedProtocolResp get_supported_protocol_resp
    RegisterResp register_resp
    DeregisterResp deregister_resp</code></pre>
<h4 class="auto-hoverlink" data-info="header"
id="sec:error-fields">7.3.3.4 Error Fields</h4>
<p><code>fixed32 err_code</code></p>
<p>This field contains a numeric code (see <a href="#sec:error-codes"
class="heading">Error Codes</a>) indicating the type of error that
caused the overall Message to fail.</p>
<p><code>string err_msg</code></p>
<p>This field contains additional information about the reason behind
the error.</p>
<p><code>repeated ParamError param_errs</code></p>
<p>This field is present in an Error Message in response to an Add, Set,
or Delete Message when the <code>allow_partial</code> field is false and
detailed error information is available for each Object or Parameter
that have caused the Message to report an Error.</p>
<h5 class="auto-hoverlink" data-info="header"
id="sec:paramerror-fields">7.3.3.4.1 ParamError Fields</h5>
<p><code>string param_path</code></p>
<p>This field contains a Path Name to the Object or Parameter that
caused the error.</p>
<p><code>fixed32 err_code</code></p>
<p>This field contains a numeric code (see <a href="#sec:error-codes"
class="heading">Error Codes</a>) indicating the type of error that
caused the Message to fail.</p>
<p><code>string err_msg</code></p>
<p>This field contains additional information about the reason behind
the error.</p>
<h2 class="auto-hoverlink" data-info="header"
id="sec:creating-updating-and-deleting-objects">7.4 Creating, Updating,
and Deleting Objects</h2>
<p>The <a href="#sec:add" class="heading">Add</a>, <a href="#sec:set"
class="heading">Set</a>, and <a href="#sec:delete"
class="heading">Delete</a> requests are used to create, configure and
remove Objects that comprise Service fields.</p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:selecting-objects-and-parameters">7.4.1 Selecting Objects and
Parameters</h3>
<p>Each Add, Set, and Delete request operates on one or more Path Names.
For the Add request, these Path Names are references to Multi-Instance
Objects. For all other requests, these Path Names can contain either
addressing based identifiers that match zero or one Object or search
based identifiers that matches one or more Objects.</p>
<p>For Add and Set requests, each Object address or search is conveyed
in a field that also contains a sub-field listing the Parameters to
update in the matched Objects.</p>
<p>The Add response contains details about the success or failure of the
creation of the Object and the Parameters set during its creation. In
addition, it also returns those Parameters that were set by the Agent
upon creation of the Object.</p>
<p>Note: The order of the data on the wire is not guaranteed to be in
the order an implementation may require to process a
<code>Message</code> piece by piece. Some common scenarios which an
Agent will need to handle:</p>
<ul>
<li>In Objects containing a union Object, the union member Object will
only exist after the discriminator Parameter was set to the associated
value</li>
<li>Key Parameters need only to have unique values after the whole
Message has been processed</li>
<li>All explicit and hidden data dependencies need to be accounted for,
so if related Parameters are changed, the order in which they occur in
the Message do not make any difference to the outcome</li>
</ul>
<p>For example, a Controller wants to create a new Wi-Fi network on an
Agent. It could use an Add Message with the following fields:</p>
<pre data-filter="pbv" type="Request"><code>    add {
      allow_partial: false
      create_objs {
        obj_path: &quot;Device.WiFi.SSID.&quot;
        param_settings {
          param: &quot;LowerLayers&quot;
          value: &quot;Device.WiFi.Radio.1.&quot;
          required: true
        }
        param_settings {
          param: &quot;SSID&quot;
          value: &quot;NewSSIDName&quot;
          required: true
        }
      }
    }</code></pre>
<p>The Agent’s response would include the Object created (with its
instance identifier) and the Unique Key Parameters of the created Object
as defined in the Device:2 Data Model <span class="citation"
data-cites="TR-181"><a href="#ref-TR-181"
role="doc-biblioref">[3]</a></span>:</p>
<pre data-filter="pbv" type="Response"><code>    add_resp {
      created_obj_results {
        requested_path: &quot;Device.WiFi.SSID.&quot;
        oper_status {
          oper_success {
            instantiated_path: &quot;Device.WiFi.SSID.4.&quot;
            unique_keys {
              key: &quot;BSSID&quot;
              value: &quot;112233445566&quot;
            }
            unique_keys {
              key: &quot;Name&quot;
              value: &quot;GuestNetwork1&quot;
            }
            unique_keys {
              key: &quot;Alias&quot;
              value: &quot;cpe-alias-1&quot;
            }
          }
        }
      }
    }</code></pre>
<h3 class="auto-hoverlink" data-info="header"
id="sec:unique-key-immutability">7.4.2 Unique Key Immutability</h3>
<p>In order to maintain addressing integrity of Multi-Instance Objects,
the following prescriptions are made on the use of Unique Keys.</p>
<p><strong><span id="r-key.1"
class="auto-hoverlink">R-KEY.1</span></strong> - Non-functional Unique
Keys (as defined in TR-106 <span class="citation" data-cites="TR-106"><a
href="#ref-TR-106" role="doc-biblioref">[2]</a></span>) MUST NOT change
in the Agent’s Instantiated Data Model after creation, as defined in <a
href="#r-add.5" class="requirement">R-ADD.5</a>.</p>
<p><strong><span id="r-key.2"
class="auto-hoverlink">R-KEY.2</span></strong> - Functional Unique Keys
(as defined in TR-106 <span class="citation" data-cites="TR-106"><a
href="#ref-TR-106" role="doc-biblioref">[2]</a></span>) MAY change
incidentally as part of normal operation, but any change MUST abide by
the uniqueness rules (i.e., no conflict with other instances).</p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:using-allow-partial-and-required-parameters">7.4.3 Using Allow
Partial and Required Parameters</h3>
<p>The Add, Set, and Delete requests contain a field called
“<code>allow_partial</code>”. This field determines whether or not the
Message should be treated as one complete configuration change, or a set
of individual changes, with regards to the success or failure of that
configuration.</p>
<p>For Delete, this is straightforward - if <code>allow_partial</code>
is <code>true</code>, the Agent returns a Response Message with
<code>affected_paths</code> and <code>unaffected_path_errs</code>
containing the successfully deleted Objects and unsuccessfully deleted
Objects, respectively. If <code>allow_partial</code> is
<code>false</code>, the Agent will return an Error Message if any
Objects fail to be deleted.</p>
<p>For the Add and Set Messages, Parameter updates contain a field
called “<code>required</code>”. This details whether or not the update
or creation of the Object should fail if a required Parameter fails.</p>
<p>This creates a hierarchy of error conditions for the Add and Set
requests, such as:</p>
<p>Parameter Error -&gt; Object Error -&gt; Message Error</p>
<p>If <code>allow_partial</code> is true, but one or more required
Parameters fail to be updated or configured, the creation or update of a
requested Path Name fails. This results in an <code>oper_failure</code>
in the <code>oper_status</code> field and
<code>updated_obj_result</code> or <code>created_obj_result</code>
returned in the Add or Set response.</p>
<p>If <code>allow_partial</code> is false, the failure of any required
Parameters will cause the update or creation of the Object to fail,
which will cause the entire Message to fail. In this case, the Agent
returns an Error Message rather than a response Message.</p>
<p><em>Note: It is up to the individual implementation whether to abort
and return an Error Message after the first error, or provide
information about multiple failures.</em></p>
<p>If the Message was at least partially successful, the response will
make use of the <code>oper_success</code> field to indicate the
successfully affected Objects.</p>
<p>The <code>oper_failure</code> and <code>oper_success</code> fields as
well as Error Messages contain a field called <code>param_errs</code>,
which contains fields of type <code>ParameterError</code> or
<code>ParamError</code>. This is so that the Controller will receive the
details of failed Parameter updates regardless of whether or not the
Agent returned a Response or Error Message.</p>
<p>The logic can be described as follows:</p>
<table style="width:100%;">
<colgroup>
<col style="width: 12%" />
<col style="width: 14%" />
<col style="width: 14%" />
<col style="width: 14%" />
<col style="width: 14%" />
<col style="width: 14%" />
<col style="width: 12%" />
</colgroup>
<thead>
<tr class="header">
<th style="text-align: right;"><code>allow_partial</code></th>
<th style="text-align: center;">Required Parameters</th>
<th style="text-align: center;">Required Parameter Failed</th>
<th style="text-align: center;">Other Parameter Failed</th>
<th style="text-align: center;">Response/Error</th>
<th style="text-align: center;">Oper_status of Object</th>
<th style="text-align: left;">Contains param_errs</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: right;"><code>true</code>/<code>false</code></td>
<td style="text-align: center;">No</td>
<td style="text-align: center;">-</td>
<td style="text-align: center;">No</td>
<td style="text-align: center;">Response</td>
<td style="text-align: center;"><code>oper_success</code></td>
<td style="text-align: left;">No</td>
</tr>
<tr class="even">
<td style="text-align: right;"><code>true</code>/<code>false</code></td>
<td style="text-align: center;">No</td>
<td style="text-align: center;">-</td>
<td style="text-align: center;">Yes</td>
<td style="text-align: center;">Response</td>
<td style="text-align: center;"><code>oper_success</code></td>
<td style="text-align: left;">Yes</td>
</tr>
<tr class="odd">
<td style="text-align: right;"><code>true</code>/<code>false</code></td>
<td style="text-align: center;">Yes</td>
<td style="text-align: center;">No</td>
<td style="text-align: center;">No</td>
<td style="text-align: center;">Response</td>
<td style="text-align: center;"><code>oper_success</code></td>
<td style="text-align: left;">No</td>
</tr>
<tr class="even">
<td style="text-align: right;"><code>true</code>/<code>false</code></td>
<td style="text-align: center;">Yes</td>
<td style="text-align: center;">No</td>
<td style="text-align: center;">Yes</td>
<td style="text-align: center;">Response</td>
<td style="text-align: center;"><code>oper_success</code></td>
<td style="text-align: left;">Yes</td>
</tr>
<tr class="odd">
<td style="text-align: right;"><code>true</code></td>
<td style="text-align: center;">Yes</td>
<td style="text-align: center;">Yes</td>
<td style="text-align: center;">-</td>
<td style="text-align: center;">Response</td>
<td style="text-align: center;"><code>oper_failure</code></td>
<td style="text-align: left;">Yes</td>
</tr>
<tr class="even">
<td style="text-align: right;"><code>false</code></td>
<td style="text-align: center;">Yes</td>
<td style="text-align: center;">Yes</td>
<td style="text-align: center;">-</td>
<td style="text-align: center;">Error</td>
<td style="text-align: center;">N/A</td>
<td style="text-align: left;">Yes</td>
</tr>
</tbody>
</table>
<h4 class="auto-hoverlink" data-info="header"
id="sec:search-paths-in-set">7.4.3.1 Search Paths and allow_partial in
Set</h4>
<p>In a Set Request that specifies a Search Path that matches multiple
objects, it is intended that the Agent treats the requested path
holistically regardless of the value of allow_partial. This represents a
special case. Information about the failure reason for any one or more
objects that failed to be created or updated is still desired, but would
be lost if an Error message was returned rather than a Response message
containing OperationFailure elements. See <a href="#r-set.2a"
class="requirement">R-SET.2a</a> and <a href="#r-set.2b"
class="requirement">R-SET.2b</a> for the specific requirements.</p>
<h3 class="auto-hoverlink" data-info="header" id="sec:add">7.4.4 The Add
Message</h3>
<p>The Add Message is used to create new Instances of Multi-Instance
Objects in the Agent’s Instantiated Data Model.</p>
<h4 class="auto-hoverlink" data-info="header"
id="sec:add-example">7.4.4.1 Add Example</h4>
<p>In this example, the Controller requests that the Agent create a new
instance in the <code>Device.LocalAgent.Controller</code> table.</p>
<pre data-filter="pbv"><code>header {
  msg_id: &quot;52867&quot;
  msg_type: ADD
}
body {
  request {
    add {
      allow_partial: true
      create_objs {
        obj_path: &quot;Device.LocalAgent.Controller.&quot;
        param_settings {
          param: &quot;Enable&quot;
          value: &quot;true&quot;
          required: false
        }
        param_settings {
          param: &quot;EndpointID&quot;
          value: &quot;controller-temp&quot;
          required: false
        }
      }
    }
  }
}</code></pre>
<pre data-filter="pbv"><code>header {
  msg_id: &quot;52867&quot;
  msg_type: ADD_RESP
}
body {
  response {
    add_resp {
      created_obj_results {
        requested_path: &quot;Device.LocalAgent.Controller.&quot;
        oper_status {
          oper_success {
            instantiated_path: &quot;Device.LocalAgent.Controller.3.&quot;
            unique_keys {
              key: &quot;EndpointID&quot;
              value: &quot;controller-temp&quot;
            }
            unique_keys {
              key: &quot;Alias&quot;
              value: &quot;cpe-alias-3&quot;
            }
          }
        }
      }
    }
  }
}</code></pre>
<h4 class="auto-hoverlink" data-info="header"
id="sec:add-request-fields">7.4.4.2 Add Request Fields</h4>
<p><code>bool allow_partial</code></p>
<p>This field tells the Agent how to process the Message in the event
that one or more of the Objects specified in the
<code>create_objs</code> argument fails creation.</p>
<p><strong><span id="r-add.0"
class="auto-hoverlink">R-ADD.0</span></strong> - If the
<code>allow_partial</code> field is set to <code>true</code>, and no
other exceptions are encountered, the Agent treats each Object matched
in <code>obj_path</code> independently. The Agent MUST complete the
creation of valid Objects regardless of the inability to create or
update one or more Objects (see <a
href="#sec:using-allow-partial-and-required-parameters"
class="heading">Using Allow Partial and Required Parameters</a>).</p>
<p><strong><span id="r-add.1"
class="auto-hoverlink">R-ADD.1</span></strong> - If the
<code>allow_partial</code> field is set to <code>false</code>, and no
other exceptions are encountered, the Agent treats each Object matched
in <code>obj_path</code> holistically. A failure to create any one
Object MUST cause the Add Message to fail and return an
<code>Error</code> Message (see <a
href="#sec:using-allow-partial-and-required-parameters"
class="heading">Using Allow Partial and Required Parameters</a>).</p>
<p><code>repeated CreateObject create_objs</code></p>
<p>This field contains a repeated set of CreateObject fields.</p>
<h5 class="auto-hoverlink" data-info="header"
id="sec:createobject-fields">7.4.4.2.1 CreateObject Fields</h5>
<p><code>string obj_path</code></p>
<p>This field contains an Object Path to a writeable Table in the
Agent’s Instantiated Data Model.</p>
<p><strong><span id="r-add.2"
class="auto-hoverlink">R-ADD.2</span></strong> - The
<code>obj_path</code> field in the <code>CreateObject</code> Message of
an Add Request MUST specify or match exactly one Object Path.
(DEPRECATED)</p>
<p><em>Note: The R-ADD.2 requirement was deprecated in USP 1.3 because
previous USP versions too narrowly restricted the usage of various paths
in the obj_path field. If multiple paths are impacted, then the AddResp
can contain multiple CreatedObjectResult instances that include the same
requested_path.</em></p>
<p><code>repeated CreateParamSetting param_settings</code></p>
<p>This field contains a repeated set of CreateParamSetting fields.</p>
<h6 class="auto-hoverlink" data-info="header"
id="sec:createparamsetting-fields">7.4.4.2.1.1 CreateParamSetting
Fields</h6>
<p><code>string param</code></p>
<p>This field contains a Relative Path to a Parameter of the Object
specified in <code>obj_path</code>, or  any Parameter in a nested tree
of single instance Sub-Objects of the Object specified in
<code>obj_path</code>.</p>
<p><em>Note: The Parameters that can be set in an Add Message are still
governed by the permissions allowed to the Controller. Should a
Controller attempt to create an Object when it does not have permission
on one or more Parameters of that Object, the expected behavior is as
follows:</em></p>
<ul>
<li><p><em>If the Add Message omits Parameters for which the Controller
does not have write permission, those parameters will be set to their
default (if any) by the Agent, and the Add Message
succeeds.</em></p></li>
<li><p><em>If the Add Message includes Parameters for which the
Controller does not have write permission, the Message proceeds in
accordance with the rules for allow_partial and required
parameters.</em></p></li>
</ul>
<p><code>string value</code></p>
<p>This field contains the value of the Parameter specified in the
<code>param</code> field that the Controller would like to configure as
part of the creation of this Object. Refer to <a
href="#sec:parameter-value-encoding" class="heading">Parameter and
Argument Value Encoding</a> for details of how Parameter values are
encoded as Protocol Buffers v3 strings.</p>
<p><code>bool required</code></p>
<p>This field specifies whether the Agent should treat the creation of
the Object specified in <code>obj_path</code> as conditional upon the
successful configuration of this Parameter (see <a
href="#sec:using-allow-partial-and-required-parameters"
class="heading">Using Allow Partial and Required Parameters</a>).</p>
<p><em>Note: Any Unique Key Parameter contained in the Add Message will
be considered as required regardless of how this field is set. This is
to ensure that Unique Key constraints are met when creating the instance
of the Object.</em></p>
<p><strong><span id="r-add.2a"
class="auto-hoverlink">R-ADD.2a</span></strong> - If the
<code>allow_partial</code> field is set to <code>false</code> and and
the <code>obj_path</code> field contains a Search Expression, a failure
in any of the Paths matched by the Search Expression MUST result in a
failure and the state of the Data Model MUST NOT change.</p>
<p><strong><span id="r-add.3"
class="auto-hoverlink">R-ADD.3</span></strong> - If the
<code>required</code> field is set to true, a failure to update this
Parameter MUST result in a failure to create the Object.</p>
<h4 class="auto-hoverlink" data-info="header"
id="sec:add-response-fields">7.4.4.3 Add Response Fields</h4>
<p><code>repeated CreatedObjectResult created_obj_results</code></p>
<p>A repeated set of <code>CreatedObjectResult</code> fields for each
<code>CreateObject</code> field in the Add Message.</p>
<h5 class="auto-hoverlink" data-info="header"
id="sec:createdobjectresult-fields">7.4.4.3.1 CreatedObjectResult
Fields</h5>
<p><code>string requested_path</code></p>
<p>This field returns the value of <code>obj_paths</code> in the
<code>CreateObject</code> Message associated with this
<code>CreatedObjectResult</code>.</p>
<p><code>OperationStatus oper_status</code></p>
<p>The field contains a Message of type <code>OperationStatus</code>
that specifies the overall status for the creation of the Object
specified in <code>requested_path</code>.</p>
<h6 class="auto-hoverlink" data-info="header"
id="sec:operationstatus-fields">7.4.4.3.1.1 OperationStatus Fields</h6>
<p><code>oneof oper_status</code></p>
<p>This field contains one of the types given below. Each indicates that
the field contains a Message of the given type.</p>
<p><code>OperationFailure oper_failure</code></p>
<p>Used when the Object given in <code>requested_path</code> failed to
be created.</p>
<p><code>OperationSuccess oper_success</code></p>
<p>Used when the <code>Add</code> Message was (at least partially)
successful.</p>
<h6 class="auto-hoverlink" data-info="header"
id="sec:operationfailure-fields">7.4.4.3.1.2 OperationFailure
Fields</h6>
<p><code>fixed32 err_code</code></p>
<p>This field contains a numeric code (<a href="#sec:error-codes"
class="heading">Error Codes</a>) indicating the type of error that
caused the Object creation to fail.</p>
<p><code>string err_msg</code></p>
<p>This field contains additional information about the reason behind
the error.</p>
<h6 class="auto-hoverlink" data-info="header"
id="sec:operation-success-fields">7.4.4.3.1.3 Operation Success
Fields</h6>
<p><code>string instantiated_path</code></p>
<p>This field contains the Object Instance Path of the created
Object.</p>
<p><code>repeated ParameterError param_errs</code></p>
<p>This field returns a repeated set of ParameterError messages.</p>
<p><strong><span id="r-add.4"
class="auto-hoverlink">R-ADD.4</span></strong> - If any of the
Parameters and values specified in the <code>param_settings</code> field
fail to configure upon creation, this set MUST include one field
describing each of the failed Parameters and the reason for their
failure.</p>
<p><code>map&lt;string, string&gt; unique_keys</code></p>
<p>This field contains a map of the Relative Path and value for all of
this Object’s Unique Key Parameters that are supported by the Agent.</p>
<p><strong><span id="r-add.5"
class="auto-hoverlink">R-ADD.5</span></strong> - If the Controller did
not include some or all of the Unique Key Parameters that are supported
by the Agent in the <code>param_settings</code> field, the Agent MUST
assign values to these Parameters and return them in the
<code>unique_keys</code> field.</p>
<p><strong><span id="r-add.6"
class="auto-hoverlink">R-ADD.6</span></strong> - If the Controller does
not have Read permission on any of the Parameters returned in
<code>unique_keys</code>, these Parameters MUST NOT be returned in this
field.</p>
<h6 class="auto-hoverlink" data-info="header"
id="sec:parametererror-fields">7.4.4.3.1.4 ParameterError Fields</h6>
<p><code>string param</code></p>
<p>This field contains the Relative Parameter Path to the Parameter that
failed to be set.</p>
<p><code>fixed32 err_code</code></p>
<p>This field contains the numeric code (<a href="#sec:error-codes"
class="heading">Error Codes</a>) of the error that caused the Parameter
set to fail.</p>
<p><code>string err_msg</code></p>
<p>This field contains text related to the error specified by
<code>err_code</code>.</p>
<h4 class="auto-hoverlink" data-info="header"
id="sec:add-message-supported-error-codes">7.4.4.4 Add Message Supported
Error Codes</h4>
<p>Appropriate error codes for the Add Message include
<code>7000-7019</code>, <code>7026</code>, and
<code>7800-7999</code>.</p>
<h3 class="auto-hoverlink" data-info="header" id="sec:set">7.4.5 The Set
Message</h3>
<p>The Set Message is used to update the Parameters of existing Objects
in the Agent’s Instantiated Data Model.</p>
<h4 class="auto-hoverlink" data-info="header"
id="sec:set-example">7.4.5.1 Set Example</h4>
<p>In this example the Controller requests that the Agent change the
value of the <code>FriendlyName</code> Parameter in the
<code>Device.DeviceInfo.</code> Object.</p>
<pre data-filter="pbv"><code>header {
  msg_id: &quot;19220&quot;
  msg_type: SET
}
body {
  request {
    set {
      allow_partial: true
      update_objs {
        obj_path: &quot;Device.DeviceInfo.&quot;
        param_settings {
          param: &quot;FriendlyName&quot;
          value: &quot;MyDevicesFriendlyName&quot;
          required: true
        }
      }
    }
  }
}</code></pre>
<pre data-filter="pbv"><code>header {
  msg_id: &quot;19220&quot;
  msg_type: SET_RESP
}
body {
  response {
    set_resp {
      updated_obj_results {
        requested_path: &quot;Device.DeviceInfo.&quot;
        oper_status {
          oper_success {
            updated_inst_results {
              affected_path: &quot;Device.DeviceInfo.&quot;
              updated_params {
                key: &quot;FriendlyName&quot;
                value: &quot;MyDevicesFriendlyName&quot;
              }
            }
          }
        }
      }
    }
  }
}</code></pre>
<h4 class="auto-hoverlink" data-info="header"
id="sec:set-request-fields">7.4.5.2 Set Request Fields</h4>
<p><code>bool allow_partial</code></p>
<p>This field tells the Agent how to process the Message in the event
that one or more of the Objects matched in the <code>obj_path</code>
fails to update.</p>
<p><strong><span id="r-set.0"
class="auto-hoverlink">R-SET.0</span></strong> - If the
<code>allow_partial</code> field is set to true, and no other exceptions
are encountered, the Agent treats each <code>UpdateObject</code> message
<code>obj_path</code> independently. The Agent MUST complete the update
of valid Objects regardless of the inability to update one or more
Objects (see <a href="#sec:using-allow-partial-and-required-parameters"
class="heading">Using Allow Partial and Required Parameters</a>).</p>
<p><em>Note: This may cause some counterintuitive behavior if there are
no required Parameters to be updated. The Set Request can still result
in a Set Response (rather than an Error Message) if
<code>allow_partial</code> is set to true.</em></p>
<p><strong><span id="r-set.1"
class="auto-hoverlink">R-SET.1</span></strong> - If the
<code>allow_partial</code> field is set to false, and no other
exceptions are encountered, the Agent treats each
<code>UpdateObject</code> message <code>obj_path</code> holistically. A
failure to update any one Object MUST cause the Set Message to fail and
return an Error Message (see <a
href="#sec:using-allow-partial-and-required-parameters"
class="heading">Using Allow Partial and Required Parameters</a>).</p>
<p><code>repeated UpdateObject update_objs</code></p>
<p>This field contains a repeated set of UpdateObject messages.</p>
<h5 class="auto-hoverlink" data-info="header"
id="sec:updateobject-fields">7.4.5.2.1 UpdateObject Fields</h5>
<p><code>string obj_path</code></p>
<p>This field contains an Object Path, Object Instance Path, or Search
Path to Objects or Object Instances in the Agent’s Instantiated Data
Model.</p>
<p><code>repeated UpdateParamSetting param_settings</code></p>
<p>The field contains a repeated set of <code>UpdatedParamSetting</code>
messages.</p>
<h6 class="auto-hoverlink" data-info="header"
id="sec:updateparamsetting-fields">7.4.5.2.1.1 UpdateParamSetting
Fields</h6>
<p><code>string param</code></p>
<p>This field contains the Relative Path of a Parameter of the Object
specified in <code>obj_path</code>.</p>
<p><code>string value</code></p>
<p>This field contains the value of the Parameter specified in the
<code>param</code> field that the Controller would like to configure.
Refer to <a href="#sec:parameter-value-encoding"
class="heading">Parameter and Argument Value Encoding</a> for details of
how Parameter values are encoded as Protocol Buffers v3 strings.</p>
<p><code>bool required</code></p>
<p>This field specifies whether the Agent should treat the update of the
Object specified in <code>obj_path</code> as conditional upon the
successful configuration of this Parameter.</p>
<p><strong><span id="r-set.2"
class="auto-hoverlink">R-SET.2</span></strong> - If the
<code>required</code> field is set to <code>true</code>, a failure to
update this Parameter MUST result in a failure to update the Object (see
<a href="#sec:using-allow-partial-and-required-parameters"
class="heading">Using Allow Partial and Required Parameters</a>).</p>
<p><strong><span id="r-set.2a"
class="auto-hoverlink">R-SET.2a</span></strong> - If the
<code>obj_path</code> field in the <code>UpdateObject</code> message of
a Set Request contains a Search Path matching more than one object, the
Agent MUST treat the results of that <code>obj_path</code> holistically,
regardless of the value of the <code>allow_partial</code> field. That
is, if any object that matches the Search Path fails to be updated due
to an error, the Agent MUST undo any changes that were already processed
due to this <code>obj_path</code>, and the Agent MUST return a Set
Response with an UpdatedObjectResult containing:</p>
<ul>
<li>A <code>requested_path</code> equal to the <code>obj_path</code> in
the request.</li>
<li>An <code>oper_status</code> field containing an OperationFailure
message.</li>
<li>At least one UpdatedInstanceFailure message with an
<code>affected_path</code> that reflects the object that failed to
update.</li>
</ul>
<p><strong><span id="r-set.2b"
class="auto-hoverlink">R-SET.2b</span></strong> - The Agent MAY
terminate processing a Set Request with an <code>obj_path</code> field
in the <code>UpdateObject</code> message that contains a Search Path
matching more than one object after encountering any number of
errors.</p>
<h4 class="auto-hoverlink" data-info="header"
id="sec:set-response">7.4.5.3 Set Response</h4>
<p><code>repeated UpdatedObjectResult updated_obj_results</code></p>
<p>This field contains a repeated set of
<code>UpdatedObjectResult</code> messages for each
<code>UpdateObject</code> message in the associated Set Request.</p>
<h5 class="auto-hoverlink" data-info="header"
id="sec:updatedobjectresult-fields">7.4.5.3.1 UpdatedObjectResult
Fields</h5>
<p><code>string requested_path</code></p>
<p>This field returns the value of <code>updated_obj_results</code> in
the <code>UpdateObject</code> message associated with this
<code>UpdatedObjectResult</code>.</p>
<p><code>OperationStatus oper_status</code></p>
<p>The field contains a message of type <code>OperationStatus</code>
that specifies the overall status for the update of the Object specified
in <code>requested_path</code>.</p>
<h6 class="auto-hoverlink" data-info="header"
id="sec:operationstatus-fields-1">7.4.5.3.1.1 OperationStatus
Fields</h6>
<p><code>oneof oper_status</code></p>
<p>This field contains a message of one of the following types.</p>
<p><code>OperationFailure oper_failure</code></p>
<p>Used when the Object specified in <code>requested_path</code> failed
to be updated.</p>
<p><code>OperationSuccess oper_success</code></p>
<p>Used when the <code>Set</code> message was (at least partially)
successful.</p>
<h6 class="auto-hoverlink" data-info="header"
id="sec:operationfailure-fields-1">7.4.5.3.1.2 OperationFailure
Fields</h6>
<p><code>fixed32 err_code</code></p>
<p>This field contains a numeric code (<a href="#sec:error-codes"
class="heading">Error Codes</a>) indicating the type of error that
caused the Object update to fail.</p>
<p><code>string err_msg</code></p>
<p>This field contains additional information about the reason behind
the error.</p>
<p><code>repeated UpdatedInstanceFailure updated_inst_failures</code></p>
<p>This field contains a repeated set of messages of type
<code>UpdatedInstanceFailure</code>.</p>
<h6 class="auto-hoverlink" data-info="header"
id="sec:updatedinstancefailure-fields">7.4.5.3.1.3
UpdatedInstanceFailure Fields</h6>
<p><code>string affected_path</code></p>
<p>This field returns the Object Path or Object Instance Path of the
Object that failed to update.</p>
<p><code>repeated ParameterError param_errs</code></p>
<p>This field contains a repeated set of <code>ParameterError</code>
messages.</p>
<h6 class="auto-hoverlink" data-info="header"
id="sec:parametererror-fields-1">7.4.5.3.1.4 ParameterError Fields</h6>
<p><code>string param</code></p>
<p>This field contains the Relative Parameter Path to the Parameter that
failed to be set.</p>
<p><code>fixed32 err_code</code></p>
<p>This field contains a numeric code (<a href="#sec:error-codes"
class="heading">Error Codes</a>) indicating the type of error that
caused the Parameter set to fail.</p>
<p><code>string err_msg</code></p>
<p>This field contains text related to the error specified by
<code>err_code</code>.</p>
<h6 class="auto-hoverlink" data-info="header"
id="sec:operationsuccess-fields">7.4.5.3.1.5 OperationSuccess
Fields</h6>
<p><code>repeated UpdatedInstanceResult updated_inst_results</code></p>
<p>This field contains a repeated set of
<code>UpdatedInstanceResult</code> messages.</p>
<h6 class="auto-hoverlink" data-info="header"
id="sec:updatedinstanceresult-fields">7.4.5.3.1.6 UpdatedInstanceResult
Fields</h6>
<p><code>string affected_path</code></p>
<p>This field returns the Object Path or Object Instance Path of the
updated Object.</p>
<p><code>repeated ParameterError param_errs</code></p>
<p>This field contains a repeated set of <code>ParameterError</code>
messages.</p>
<p><code>map&lt;string, string&gt; updated_params</code></p>
<p>This field returns a set of key/value pairs containing a Relative
Parameter Path (relative to the <code>affected_path</code>) to each of
the Parameters updated by the Set Request and its value after the
update. Refer to <a href="#sec:parameter-value-encoding"
class="heading">Parameter and Argument Value Encoding</a> for details of
how Parameter values are encoded as Protocol Buffers v3 strings.</p>
<p><strong><span id="r-set.3"
class="auto-hoverlink">R-SET.3</span></strong> - If the Controller does
not have Read permission on any of the Parameters specified in
<code>updated_params</code>, these Parameters MUST NOT be returned in
this field.</p>
<p><em>Note: If the Set Request configured a Parameter to the same value
it already had, this Parameter is still returned in the
<code>updated_params</code>.</em></p>
<h6 class="auto-hoverlink" data-info="header"
id="sec:parametererror-fields-2">7.4.5.3.1.7 ParameterError Fields</h6>
<p><code>string param</code></p>
<p>This field contains the Parameter Path to the Parameter that failed
to be set.</p>
<p><code>fixed32 err_code</code></p>
<p>This field contains a numeric code (<a href="#sec:error-codes"
class="heading">Error Codes</a>) indicating the type of error that
caused the Parameter set to fail.</p>
<p><code>string err_msg</code></p>
<p>This field contains text related to the error specified by
<code>err_code</code>.</p>
<h4 class="auto-hoverlink" data-info="header"
id="sec:set-message-supported-error-codes">7.4.5.4 Set Message Supported
Error Codes</h4>
<p>Appropriate error codes for the Set Message include
<code>7000-7016</code>, <code>7020</code>, <code>7021</code>,
<code>7026</code>, and <code>7800-7999</code>.</p>
<h3 class="auto-hoverlink" data-info="header" id="sec:delete">7.4.6 The
Delete Message</h3>
<p>The Delete Message is used to remove Instances of Multi-Instance
Objects in the Agent’s Instantiated Data Model.</p>
<h4 class="auto-hoverlink" data-info="header"
id="sec:delete-example">7.4.6.1 Delete Example</h4>
<p>In this example, the Controller requests that the Agent remove the
instance in <code>Device.LocalAgent.Controller</code> table that has the
EndpointID value of “<code>controller-temp</code>”.</p>
<pre data-filter="pbv"><code>header {
  msg_id: &quot;24799&quot;
  msg_type: DELETE
}
body {
  request {
    delete {
      allow_partial: false
      obj_paths: &#39;Device.LocalAgent.Controller.[EndpointID==&quot;controller-temp&quot;].&#39;
    }
  }
}</code></pre>
<pre data-filter="pbv"><code>header {
  msg_id: &quot;24799&quot;
  msg_type: DELETE_RESP
}
body {
  response {
    delete_resp {
      deleted_obj_results {
        requested_path: &#39;Device.LocalAgent.Controller.[EndpointID==&quot;controller-temp&quot;].&#39;
        oper_status {
          oper_success {
            affected_paths: &quot;Device.LocalAgent.Controller.31185.&quot;
          }
        }
      }
    }
  }
}</code></pre>
<h4 class="auto-hoverlink" data-info="header"
id="sec:delete-request-fields">7.4.6.2 Delete Request Fields</h4>
<p><code>bool allow_partial</code></p>
<p>This field tells the Agent how to process the Message in the event
that one or more of the Objects specified in the <code>obj_path</code>
argument fails deletion.</p>
<p><strong><span id="r-del.0"
class="auto-hoverlink">R-DEL.0</span></strong> - If the
<code>allow_partial</code> field is set to true, and no other exceptions
are encountered, the Agent treats each entry in <code>obj_path</code>
independently. The Agent MUST complete the deletion of valid Objects
regardless of the inability to delete one or more Objects (see <a
href="#sec:using-allow-partial-and-required-parameters"
class="heading">Using Allow Partial and Required Parameters</a>).</p>
<p><strong><span id="r-del.1"
class="auto-hoverlink">R-DEL.1</span></strong> - If the
<code>allow_partial</code> field is set to false, the Agent treats each
entry in <code>obj_path</code> holistically. Any entry referring to an
Object which is non-deletable or doesn’t exist in the supported data
model MUST cause the Delete Message to fail and return an Error
Message.</p>
<p><code>repeated string obj_paths</code></p>
<p>This field contains a repeated set of Object Instance Paths or Search
Paths.</p>
<h4 class="auto-hoverlink" data-info="header"
id="sec:delete-response-fields">7.4.6.3 Delete Response Fields</h4>
<p><code>repeated DeletedObjectResult deleted_obj_results</code></p>
<p>This field contains a repeated set of
<code>DeletedObjectResult</code> messages.</p>
<h5 class="auto-hoverlink" data-info="header"
id="sec:deletedobjectresult-fields">7.4.6.3.1 DeletedObjectResult
Fields</h5>
<p><code>string requested_path</code></p>
<p>This field returns the value of the entry of <code>obj_paths</code>
(in the Delete Request) associated with this
<code>DeleteObjectResult</code>.</p>
<p><code>OperationStatus oper_status</code></p>
<p>This field contains a message of type
<code>OperationStatus</code>.</p>
<h6 class="auto-hoverlink" data-info="header"
id="sec:operationstatus-fields-2">7.4.6.3.1.1 OperationStatus
Fields</h6>
<p><code>oneof oper_status</code></p>
<p>This field contains a message of one of the following types.</p>
<p><code>OperationFailure oper_failure</code></p>
<p>Used when the Object specified in <code>requested_path</code> failed
to be deleted.</p>
<p><code>OperationSuccess oper_success</code></p>
<p>Used when the <code>Delete</code> Message was (at least partially)
successful.</p>
<h6 class="auto-hoverlink" data-info="header"
id="sec:operationfailure-fields-2">7.4.6.3.1.2 OperationFailure
Fields</h6>
<p><code>fixed32 err_code</code></p>
<p>This field contains a numeric code (<a href="#sec:error-codes"
class="heading">Error Codes</a>) indicating the type of error that
caused the delete to fail.</p>
<p><code>string err_msg</code></p>
<p>This field contains additional information about the reason behind
the error.</p>
<h6 class="auto-hoverlink" data-info="header"
id="sec:operationsuccess-fields-1">7.4.6.3.1.3 OperationSuccess
Fields</h6>
<p><code>repeated string affected_paths</code></p>
<p>This field returns a repeated set of Path Names to Object
Instances.</p>
<p><strong><span id="r-del.2"
class="auto-hoverlink">R-DEL.2</span></strong> - If the Controller does
not have Read permission on any of the Objects specified in
<code>affected_paths</code>, these Objects MUST NOT be returned in this
field.</p>
<p><strong><span id="r-del.2a"
class="auto-hoverlink">R-DEL.2a</span></strong> - If the requested_path
was valid (i.e., properly formatted and in the Agent’s supported data
model) but did not resolve to any Objects in the Agent’s instantiated
data model, the Agent MUST return an OperationSuccess for this
requested_path, and include an empty set for affected_path.</p>
<p><code>repeated UnaffectedPathError unaffected_path_errs</code></p>
<p>This field contains a repeated set of messages of type
<code>UnaffectedPathError</code>.</p>
<p><strong><span id="r-del.3"
class="auto-hoverlink">R-DEL.3</span></strong> - This set MUST include
one <code>UnaffectedPathError</code> message for each Object Instance
that exists in the Agent’s instantiated data model and were matched by
the Path Name specified in <code>obj_path</code> and failed to
delete.</p>
<p><strong><span id="r-del.4"
class="auto-hoverlink">R-DEL.4</span></strong> - If the Controller does
not have Read permission on any of the Objects specified in
<code>unaffected_paths</code>, these Objects MUST NOT be returned in
this field.</p>
<h6 class="auto-hoverlink" data-info="header"
id="sec:unaffectedpatherror-fields">7.4.6.3.1.4 UnaffectedPathError
Fields</h6>
<p><code>string unaffected_path</code></p>
<p>This field returns the Path Name to the Object Instance that failed
to be deleted.</p>
<p><code>fixed32 err_code</code></p>
<p>This field contains a numeric code (<a href="#sec:error-codes"
class="heading">Error Codes</a>) indicating the type of the error that
caused the deletion of this Object to fail.</p>
<p><code>string err_msg</code></p>
<p>This field contains text related to the error specified by
<code>err_code</code>.</p>
<h4 class="auto-hoverlink" data-info="header"
id="sec:delete-message-supported-error-codes">7.4.6.4 Delete Message
Supported Error Codes</h4>
<p>Appropriate error codes for the Delete Message include
<code>7000-7008</code>, <code>7015</code>, <code>7016</code>,
<code>7018</code>, <code>7024</code>, <code>7026</code> and
<code>7800-7999</code>.</p>
<h2 class="auto-hoverlink" data-info="header"
id="sec:reading-an-agents-state-and-capabilities">7.5 Reading an Agent’s
State and Capabilities</h2>
<p>An Agent’s current state and capabilities are represented in its data
model. The current state is referred to as its Instantiated Data Model,
while the data model that represents its set of capabilities is referred
to as its Supported Data Model. Messages exist to retrieve data from
both the instantiated and Supported Data Models.</p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:the-get-message">7.5.1 The Get Message</h3>
<p>The basic Get Message is used to retrieve the values of a set of
Object’s Parameters in order to learn an Agent’s current state. It takes
a set of Path Names as an input and returns the complete tree of all
Objects and Sub-Objects of any Object matched by the specified
expressions, along with each Object’s Parameters and their values. The
Search Paths specified in a Get request can also target individual
Parameters within Objects to be returned.</p>
<p><em>Note: Those familiar with Broadband Forum TR-069 <span
class="citation" data-cites="TR-069"><a href="#ref-TR-069"
role="doc-biblioref">[1]</a></span> will recognize this behavior as the
difference between “Partial Paths” and “Complete Paths”. This behavior
is replicated in USP for the Get Message for each Path Name that is
matched by the expression(s) supplied in the request.</em></p>
<p><em>Note: Each Search Path is intended to be evaluated separately,
and the results from a given Search Path are returned in a field
dedicated to that Path Name. As such, it is possible that the same
information may be returned from more than one Search Path. This is
intended, and the Agent should treat each Search Path
atomically.</em></p>
<p>The response returns a <code>req_path_results</code> entry for each
Path Name given in <code>param_paths</code>. If a Path expression
specified in the request does not match any valid Parameters or Objects,
the response will indicate that this expression was an “Invalid Path”,
indicating that the Object or Parameter does not currently exist in the
Agent’s Supported Data Model.</p>
<p>Each <code>req_path_results</code> message given in the response
contains a set of <code>resolved_path_results</code> messages for each
Object and Sub-Object relative to the Path resolved by the
<code>param_paths</code> element. Each results is followed by a list of
Parameters (<code>result_params</code>) and their values. If there are
no Parameters, <code>result_params</code> may be empty. These Parameter
Paths are Relative Paths to the <code>resolved_path</code>. <em>Note:
This behavior has been clarified as of USP 1.2. Previous versions
implied that Sub-Object Parameters be returned as Relative Paths to the
original <code>resolved_path</code> in a single
<code>result_params</code> list. In USP 1.2, each Sub-Object is returned
in its own <code>resolved_path</code>.</em></p>
<p>The tree depth of a Get response can be limited by specifying a
non-zero value for the <code>max_depth</code> field in Get request. If
<code>max_depth</code> field is present and not <code>0</code> then the
Agent will limit the maximum depth of each returned
<code>req_path_results</code> to a tree rooted in
<code>requested_path</code> with a depth specified by
<code>max_depth</code> value.</p>
<p><em>Note: The <code>max_depth</code> field was introduced in USP 1.2.
If this field is not present in a Get request or has a value of
<code>0</code>, the Agent returns the complete tree of all Objects and
Sub-Objects of all the Path Names mentioned in <code>param_paths</code>.
This is the same as the behavior specified for prior USP versions. An
Agent implementing a prior version of the USP specification will ignore
the field and behave as if the <code>max_depth</code> field was set to
<code>0</code>.</em></p>
<h4 class="auto-hoverlink" data-info="header"
id="sec:get-examples">7.5.1.1 Get Examples</h4>
<p>The following table illustrates the result params for one of the Path
Names mentioned in <code>param_paths</code> is
<code>Device.DeviceInfo.</code> and example values of the
<code>max_depth</code> Get request field.</p>
<table style="width:100%;">
<colgroup>
<col style="width: 31%" />
<col style="width: 36%" />
<col style="width: 31%" />
</colgroup>
<thead>
<tr class="header">
<th style="text-align: right;"><code>max_depth</code></th>
<th style="text-align: center;"><code>param_paths</code></th>
<th style="text-align: left;"><code>result_params</code></th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: right;"><code>0</code></td>
<td style="text-align: center;"><code>Device.DeviceInfo.</code></td>
<td style="text-align: left;">All the Parameters of
<code>Device.DeviceInfo.</code> and all of its Sub-Objects (like
<code>Device.DeviceInfo.TemperatureStatus.</code> and
<code>Device.DeviceInfo.TemperatureStatus.TemperatureSensor.{i}.</code>)
along with their values</td>
</tr>
<tr class="even">
<td style="text-align: right;"><code>1</code></td>
<td style="text-align: center;"><code>Device.DeviceInfo.</code></td>
<td style="text-align: left;">All the Parameters of
<code>Device.DeviceInfo.</code> and their values only</td>
</tr>
<tr class="odd">
<td style="text-align: right;"><code>2</code></td>
<td style="text-align: center;"><code>Device.DeviceInfo.</code></td>
<td style="text-align: left;">All the Parameters of
<code>Device.DeviceInfo.</code> and its first level Sub-Objects(like
<code>Device.DeviceInfo.TemperatureStatus.</code>) along with their
values</td>
</tr>
<tr class="even">
<td style="text-align: right;"><code>3</code></td>
<td style="text-align: center;"><code>Device.DeviceInfo.</code></td>
<td style="text-align: left;">All the Parameters of
<code>Device.DeviceInfo.</code> and its first and second level
Sub-Objects (like <code>Device.DeviceInfo.TemperatureStatus.</code> and
<code>Device.DeviceInfo.TemperatureStatus.TemperatureSensor.{i}.</code>)
along with their values</td>
</tr>
</tbody>
</table>
<p>For example, a Controller wants to read the data model to learn the
settings and <code>Stats</code> of a single Wi-Fi SSID, “HomeNetwork”
with a BSSID of “00:11:22:33:44:55”. It could use a Get request with the
following fields:</p>
<pre data-filter="pbv" type="Request"><code>    get {
      param_paths: &#39;Device.WiFi.SSID.[SSID==&quot;HomeNetwork&quot;&amp;&amp;BSSID==&quot;00:11:22:33:44:55&quot;].&#39;
      max_depth: 2
    }</code></pre>
<p>In response to this request the Agent returns all Parameters, plus
the Parameters of any Sub-Objects, of the addressed instance. Had
<code>max_depth</code> been set to <code>1</code> then all of the SSID
Parameters and their values would have been returned, but the
<code>Stats</code> Sub-Object and its Parameters would have been
omitted. The Agent returns this data in the Get response using a field
for each of the requested Path Names. In this case:</p>
<pre data-filter="pbv" type="Response"><code>    get_resp {
      req_path_results {
        requested_path: &#39;Device.WiFi.SSID.[SSID==&quot;HomeNetwork&quot;&amp;&amp;BSSID==&quot;00:11:22:33:44:55&quot;].&#39;
        resolved_path_results {
          resolved_path: &quot;Device.WiFi.SSID.1.&quot;
          result_params {
            key: &quot;Enable&quot;
            value: &quot;true&quot;
          }
          result_params {
            key: &quot;Status&quot;
            value: &quot;Up&quot;
          }
          result_params {
            key: &quot;Alias&quot;
            value: &quot;cpe-alias-1&quot;
          }
          result_params {
            key: &quot;Name&quot;
            value: &quot;Home Network&quot;
          }
          result_params {
            key: &quot;LastChange&quot;
            value: &quot;864000&quot;
          }
          result_params {
            key: &quot;BSSID&quot;
            value: &quot;00:11:22:33:44:55&quot;
          }
          result_params {
            key: &quot;SSID&quot;
            value: &quot;HomeNetwork&quot;
          }
        }

        resolved_path_results {
          resolved_path: &quot;Device.WiFi.SSID.1.Stats.&quot;
          result_params {
            key: &quot;BytesSent&quot;
            value: &quot;24901567&quot;
          }
          result_params {
            key: &quot;BytesReceived&quot;
            value: &quot;892806908296&quot;
          }

#           (etc.)


        }
      }
    }</code></pre>
<p>In another example, the Controller only wants to read the current
status of the Wi-Fi network with the SSID “HomeNetwork” with the BSSID
of 00:11:22:33:44:55. It could use a Get request with the following
fields:</p>
<pre data-filter="pbv" type="Request"><code>    get {
      param_paths: &#39;Device.WiFi.SSID.[SSID==&quot;HomeNetwork&quot;&amp;&amp;BSSID==&quot;00:11:22:33:44:55&quot;].Status&#39;
    }</code></pre>
<p>In response to this request the Agent returns only the Status
Parameter and its value.</p>
<pre data-filter="pbv" type="Response"><code>    get_resp {
      req_path_results {
        requested_path: &#39;Device.WiFi.SSID.[SSID==&quot;HomeNetwork&quot;&amp;&amp;BSSID==&quot;00:11:22:33:44:55&quot;].Status&#39;
        resolved_path_results {
          resolved_path: &quot;Device.WiFi.SSID.1.&quot;
          result_params {
            key: &quot;Status&quot;
            value: &quot;Up&quot;
          }
        }
      }
    }</code></pre>
<p>Lastly, using wildcards or another Search Path, the requested Path
Name may resolve to more than one resolved Path Names. For example for a
Request sent to an Agent with two <code>WiFi.SSID</code> instances:</p>
<pre data-filter="pbv" type="Request"><code>    get {
      param_paths: &quot;Device.WiFi.SSID.*.Status&quot;
    }</code></pre>
<p>The Agent’s response would be:</p>
<pre data-filter="pbv" type="Response"><code>    get_resp {
      req_path_results {
        requested_path: &quot;Device.WiFi.SSID.*.Status&quot;
        resolved_path_results {
          resolved_path: &quot;Device.WiFi.SSID.1.&quot;
          result_params {
            key: &quot;Status&quot;
            value: &quot;Up&quot;
          }
        }
        resolved_path_results {
          resolved_path: &quot;Device.WiFi.SSID.2.&quot;
          result_params {
            key: &quot;Status&quot;
            value: &quot;Up&quot;
          }
        }
      }
    }</code></pre>
<p>In an example with full USP Message header and body, the Controller
requests all Parameters of the MTP table entry that contains the
<code>Alias</code> value “WS-MTP1”, and the value of the
<code>Enable</code> Parameter of the <code>Subscription</code> table
where the value of the Parameter <code>ID</code> is “boot-1” and the
<code>Recipient</code> Parameter has a value of
“Device.LocalAgent.Controller.1”:</p>
<pre data-filter="pbv"><code>header {
  msg_id: &quot;5721&quot;
  msg_type: GET
}
body {
  request {
    get {
      param_paths: &#39;Device.LocalAgent.MTP.[Alias==&quot;WS-MTP1&quot;].&#39;
      param_paths: &#39;Device.LocalAgent.Subscription.[ID==&quot;boot-1&quot;&amp;&amp;Recipient==&quot;Device.LocalAgent.Controller.1&quot;].Enable&#39;
    }
  }
}</code></pre>
<pre data-filter="pbv"><code>header {
  msg_id: &quot;5721&quot;
  msg_type: GET_RESP
}
body {
  response {
    get_resp {
      req_path_results {
        requested_path: &#39;Device.LocalAgent.MTP.[Alias==&quot;WS-MTP1&quot;].&#39;
        resolved_path_results {
          resolved_path: &quot;Device.LocalAgent.MTP.5156.&quot;
          result_params {
            key: &quot;Alias&quot;
            value: &quot;WS-MTP1&quot;
          }
          result_params {
            key: &quot;Enable&quot;
            value: &quot;true&quot;
          }
          result_params {
            key: &quot;Status&quot;
            value: &quot;Up&quot;
          }
          result_params {
            key: &quot;Protocol&quot;
            value: &quot;WebSocket&quot;
          }
          result_params {
            key: &quot;EnableMDNS&quot;
            value: &quot;false&quot;
          }
        }
        resolved_path_results {
          resolved_path: &quot;Device.LocalAgent.MTP.5156.WebSocket.&quot;
          result_params {
            key: &quot;Interfaces&quot;
            value: &quot;Device.IP.Interface.1.&quot;
          }
          result_params {
            key: &quot;Port&quot;
            value: &quot;5684&quot;
          }
          result_params {
            key: &quot;Path&quot;
            value: &quot;usp-controller&quot;
          }
          result_params {
            key: &quot;EnableEncryption&quot;
            value: &quot;true&quot;
          }
        }
      }

      req_path_results {
        requested_path: &#39;Device.LocalAgent.Subscription.[ID==&quot;boot-1&quot;&amp;&amp;Recipient==&quot;Device.LocalAgent.Controller.1&quot;].Enable&#39;
        err_code: 0
        err_msg: &quot;&quot;
        resolved_path_results {
          resolved_path: &quot;Device.LocalAgent.Subscription.6629.&quot;
          result_params {
            key: &quot;Enable&quot;
            value: &quot;true&quot;
          }
        }
      }
    }
  }
}</code></pre>
<h4 class="auto-hoverlink" data-info="header"
id="sec:get-request-fields">7.5.1.2 Get Request Fields</h4>
<p><code>repeated string param_paths</code></p>
<p>This field is a set of Object Paths, Object Instance Paths, Parameter
Paths, or Search Paths to Objects and Parameters in an Agent’s
Instantiated Data Model.</p>
<p><code>fixed32 max_depth</code></p>
<p>This field limits the maximum depth of each returned
<code>result_params</code> tree to the depth specified by
<code>max_depth</code> value. A value of <code>0</code> returns the
complete tree of all Objects and Sub-Objects of all the Path Names
mentioned in <code>param_paths</code>.</p>
<p><strong><span id="r-get.5"
class="auto-hoverlink">R-GET.5</span></strong> - If the
<code>max_depth</code> field is present and contains a value other than
0, then the Agent MUST limit the tree depth of the resolved Sub-Objects
included in the <code>resolved_path_results</code> field of the Response
to the specified value.</p>
<h4 class="auto-hoverlink" data-info="header"
id="sec:get-response-fields">7.5.1.3 Get Response Fields</h4>
<p><code>repeated RequestedPathResult req_path_results</code></p>
<p>A repeated set of <code>RequestedPathResult</code> messages for each
of the Path Names given in the associated Get request.</p>
<h5 class="auto-hoverlink" data-info="header"
id="sec:requestedpathresult-field">7.5.1.3.1 RequestedPathResult
Field</h5>
<p><code>string requested_path</code></p>
<p>This field contains one of the Path Names or Search Paths given in
the <code>param_path</code> field of the associated Get Request.</p>
<p><code>fixed32 err_code</code></p>
<p>This field contains a numeric code (<a href="#sec:error-codes"
class="heading">Error Codes</a>) indicating the type of error that
caused the Get to fail on this Path Names. A value of 0 indicates the
Path Name could be read successfully.</p>
<p><strong><span id="r-get.0"
class="auto-hoverlink">R-GET.0</span></strong> - If
<code>requested_path</code> contains a Path Name (that is not a Search
Path) that does not match any Object or Parameter in the Agent’s
Instantiated Data Model, or <code>requested_path</code> contains a
Search Path that does not match any Object or Parameter in the Agent’s
Supported Data Model, the Agent MUST use the
<code>7026 - Invalid Path</code> error in this
<code>RequestedPathResult</code>.</p>
<p><strong><span id="r-get.1"
class="auto-hoverlink">R-GET.1</span></strong> - If the Controller
making the Request does not have Read permission on an Object or
Parameter matched through the <code>requested_path</code> field, the
Object or Parameter MUST be treated as if it is not present in the
Agent’s Supported data model.</p>
<p><code>string err_msg</code></p>
<p>This field contains additional information about the reason behind
the error.</p>
<p><code>repeated ResolvedPathResult resolved_path_results</code></p>
<p>This field contains one message of type ResolvedPathResult for each
Path Name resolved by the Path Name or Search Path given by
<code>requested_path</code>.</p>
<p><strong><span id="r-get.1a"
class="auto-hoverlink">R-GET.1a</span></strong> - If the
<code>requested_path</code> is a valid Search Path (i.e., properly
formatted and in the Agent’s supported data model) but did not resolve
to any Objects in the Agent’s Instantiated Data Model, the
<code>resolved_path_results</code> set MUST be empty and is not
considered an error.</p>
<p><strong><span id="r-get.1b"
class="auto-hoverlink">R-GET.1b</span></strong> - If the
<code>requested_path</code> is a valid Object Path (i.e., properly
formatted and in the Agent’s supported data model), which is not a
Search Path, but the Object does not have any Sub-Objects or Parameters,
the <code>resolved_path_results</code> set MUST be empty and is not
considered an error.</p>
<h6 class="auto-hoverlink" data-info="header"
id="sec:resolvedpathresult-fields">7.5.1.3.1.1 ResolvedPathResult
Fields</h6>
<p><code>string resolved_path</code></p>
<p>This field contains a Path Name to an Object or Object Instance that
was resolved from the Path Name or Search Path given in
<code>requested_path</code>.</p>
<p><strong><span id="r-get.2"
class="auto-hoverlink">R-GET.2</span></strong> - If the
<code>requested_path</code> included a Path Name to a Parameter, the
<code>resolved_path</code> MUST contain only the Path Name to the parent
Object or Object Instance of that Parameter.</p>
<p><code>map&lt;string, string&gt; result_params</code></p>
<p>This field contains a set of mapped key/value pairs listing a
Parameter Path (relative to the Path Name in <code>resolved_path</code>)
to each of the Parameters and their values of the Object given in
<code>resolved_path</code>. Refer to <a
href="#sec:parameter-value-encoding" class="heading">Parameter and
Argument Value Encoding</a> for details of how Parameter values are
encoded as Protocol Buffers v3 strings.</p>
<p><strong><span id="r-get.3"
class="auto-hoverlink">R-GET.3</span></strong> - If the
<code>requested_path</code> included a Path Name to a Parameter,
<code>result_params</code> MUST contain only the Parameter included in
that Path Name.</p>
<p><strong><span id="r-get.4"
class="auto-hoverlink">R-GET.4</span></strong> - If the Controller does
not have Read permission on any of the Parameters specified in
<code>result_params</code>, these Parameters MUST NOT be returned in
this field. This MAY result in this field being empty.</p>
<h4 class="auto-hoverlink" data-info="header"
id="sec:get-message-supported-error-codes">7.5.1.4 Get Message Supported
Error Codes</h4>
<p>Appropriate error codes for the Get Message include
<code>7000-7006</code>, <code>7008</code>, <code>7010</code>,
<code>7016</code>, <code>7026</code> and <code>7800-7999</code>.</p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:getinstances">7.5.2 The GetInstances Message</h3>
<p>The GetInstances Message takes a Path Name to an Object and requests
that the Agent return the Instances of that Object that exist and
<em>possibly</em> any Multi-Instance Sub-Objects that exist as well as
their Instances. This is used for getting a quick map of the
Multi-Instance Objects (i.e., Tables) the Agent currently represents,
and their Unique Key Parameters, so that they can be addressed and
manipulated later.</p>
<p>GetInstances takes one or more Path Names to Multi-Instance Objects
in a Request to an Agent. In addition, both GetInstances and
GetSupportedDM (below) make use of a flag called
<code>first_level_only</code>, which determines whether or not the
Response should include all of the Sub-Objects that are children of the
Object specified in <code>obj_path</code>. A value of <code>true</code>
means that the Response returns data <em>only</em> for the Object
specified. A value of false means that all Sub-Objects will be resolved
and returned.</p>
<h4 class="auto-hoverlink" data-info="header"
id="sec:getinstances-examples">7.5.2.1 GetInstances Examples</h4>
<p>For example, if a Controller wanted to know <em>only</em> the current
instances of Wi-Fi SSID Objects that exist on an Agent (that has 2
SSIDs), it would send a GetInstances Request as:</p>
<pre data-filter="pbv" type="Request"><code>    get_instances {
      obj_paths: &quot;Device.WiFi.SSID.&quot;
      first_level_only: true
    }</code></pre>
<p>The Agent’s Response would contain:</p>
<pre data-filter="pbv" type="Response"><code>    get_instances_resp {
      req_path_results {
        requested_path: &quot;Device.WiFi.SSID.&quot;
        curr_insts {
          instantiated_obj_path: &quot;Device.WiFi.SSID.1.&quot;
          unique_keys {
            key: &quot;Alias&quot;
            value: &quot;UserWiFi1&quot;
          }
          unique_keys {
            key: &quot;Name&quot;
            value: &quot;UserWiFi1&quot;
          }
          unique_keys {
            key: &quot;BSSID&quot;
            value: &quot;00:11:22:33:44:55&quot;
          }
        }

        curr_insts {
          instantiated_obj_path: &quot;Device.WiFi.SSID.2.&quot;
          unique_keys {
            key: &quot;Alias&quot;
            value: &quot;UserWiFi2&quot;
          }
          unique_keys {
            key: &quot;Name&quot;
            value: &quot;UserWiFi2&quot;
          }
          unique_keys {
            key: &quot;BSSID&quot;
            value: &quot;11:22:33:44:55:66&quot;
          }
        }
      }
    }</code></pre>
<p>In another example, the Controller wants to get all of the Instances
of the <code>Device.WiFi.AccessPoint</code> table, plus all of the
instances of the AssociatedDevice Object and AC Object (Sub-Objects of
AccessPoint). It would issue a GetInstances Request with the
following:</p>
<pre data-filter="pbv" type="Request"><code>    get_instances {
      obj_paths: &quot;Device.WiFi.AccessPoint.&quot;
      first_level_only: false
    }</code></pre>
<p>The Agent’s Response will contain an entry in <code>curr_insts</code>
for all of the Instances of the <code>Device.WiFi.AccessPoint</code>
table, plus the Instances of the Multi-Instance Sub-Objects
<code>.AssociatedDevice.</code> and <code>.AC.</code>:</p>
<pre data-filter="pbv" type="Response"><code>    get_instances_resp {
      req_path_results {
        requested_path: &quot;Device.WiFi.AccessPoint.&quot;
        curr_insts {
          instantiated_obj_path: &quot;Device.WiFi.AccessPoint.1.&quot;
          unique_keys {
            key: &quot;Alias&quot;
            value: &quot;cpe-alias-1&quot;
          }
          unique_keys {
            key: &quot;SSIDReference&quot;
            value: &quot;Device.WiFi.SSID.1&quot;
          }
        }
        curr_insts {
          instantiated_obj_path: &quot;Device.WiFi.AccessPoint.1.AssociatedDevice.1.&quot;
          unique_keys {
            key: &quot;MACAddress&quot;
            value: &quot;11:22:33:44:55:66&quot;
          }
        }
        curr_insts {
          instantiated_obj_path: &quot;Device.WiFi.AccessPoint.1.AC.1.&quot;
          unique_keys {
            key: &quot;AccessCategory&quot;
            value: &quot;BE&quot;
          }
        }

        curr_insts {
          instantiated_obj_path: &quot;Device.WiFi.AccessPoint.2.&quot;
          unique_keys {
            key: &quot;Alias&quot;
            value: &quot;cpe-alias-2&quot;
          }
          unique_keys {
            key: &quot;SSIDReference&quot;
            value: &quot;Device.WiFi.SSID.2&quot;
          }
        }
        curr_insts {
          instantiated_obj_path: &quot;Device.WiFi.AccessPoint.2.AssociatedDevice.1.&quot;
          unique_keys {
            key: &quot;MACAddress&quot;
            value: &quot;11:22:33:44:55:66&quot;
          }
        }
        curr_insts {
          instantiated_obj_path: &quot;Device.WiFi.AccessPoint.2.AC.1.&quot;
          unique_keys {
            key: &quot;AccessCategory&quot;
            value: &quot;BE&quot;
          }
        }
      }
    }</code></pre>
<p>Or more, if more Object Instances exist.</p>
<h4 class="auto-hoverlink" data-info="header"
id="sec:getinstances-request-fields">7.5.2.2 GetInstances Request
Fields</h4>
<p><code>repeated string obj_paths</code></p>
<p>This field contains a repeated set of Path Names or Search Paths to
Multi-Instance Objects in the Agent’s Instantiated Data Model.</p>
<p><code>bool first_level_only</code></p>
<p>This field, if <code>true</code>, indicates that the Agent returns
only those instances in the Object(s) matched by the Path Name or Search
Path in <code>obj_path</code>, and not return any child Objects.</p>
<h4 class="auto-hoverlink" data-info="header"
id="sec:getinstances-response-fields">7.5.2.3 GetInstances Response
Fields</h4>
<p><code>repeated RequestedPathResult req_path_results</code></p>
<p>This field contains a RequestedPathResult message for each Path Name
or Search</p>
<p><code>string requested_path</code></p>
<p>This field contains one of the Path Names or Search Paths given in
<code>obj_path</code> of the associated GetInstances Request.</p>
<p><code>fixed32 err_code</code></p>
<p>This field contains a numeric code (<a href="#sec:error-codes"
class="heading">Error Codes</a>) indicating the type of error that
caused the GetInstances to fail on this Path Name. A value of 0
indicates the Path Name could be read successfully.</p>
<p><strong><span id="r-gin.0"
class="auto-hoverlink">R-GIN.0</span></strong> - If the Controller
making the Request does not have Read permission on an Object or
Parameter used for matching through the <code>requested_path</code>
field, any otherwise matched Object MUST be treated as if it is not
present in the Agent’s Instantiated Data Model</p>
<p><code>string err_msg</code></p>
<p>This field contains additional information about the reason behind
the error.</p>
<p><code>repeated CurrInstance curr_insts</code></p>
<p>This field contains a message of type <code>CurrInstance</code> for
each Instance of <em>all</em> of the Objects matched by
<code>requested_path</code> that exists in the Agent’s Instantiated Data
Model.</p>
<h6 class="auto-hoverlink" data-info="header"
id="sec:currinstance-fields">7.5.2.3.0.1 CurrInstance Fields</h6>
<p><code>string instantiated_obj_path</code></p>
<p>This field contains the Object Instance Path of the Object.</p>
<p><code>map&lt;string, string&gt; unique_keys</code></p>
<p>This field contains a map of key/value pairs for all of this Object’s
Unique Key Parameters that are supported by the Agent.</p>
<p><strong><span id="r-gin.1"
class="auto-hoverlink">R-GIN.1</span></strong> - If the Controller does
not have Read permission on any of the Parameters specified in
<code>unique_keys</code>, these Parameters MUST NOT be returned in this
field.</p>
<h4 class="auto-hoverlink" data-info="header"
id="sec:getinstances-error-codes">7.5.2.4 GetInstances Error Codes</h4>
<p>Appropriate error codes for the GetInstances Message include
<code>7000-7006</code>, <code>7008</code>, <code>7016</code>,
<code>7018</code>, <code>7026</code> and <code>7800-7999</code>.</p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:the-getsupporteddm-message">7.5.3 The GetSupportedDM
Message</h3>
<p>GetSupportedDM (referred to informally as GSDM) is used to retrieve
the Objects, Parameters, Events, and Commands in the Agent’s Supported
Data Model. This allows a Controller to learn what an Agent understands,
rather than its current state.</p>
<p>The GetSupportedDM Message is different from other USP Messages in
that it only returns information about the Agent’s Supported Data Model.
This means that Path Names to Multi-Instance Objects only address the
Object itself, rather than Instances of the Object, and those Path Names
that contain Multi-Instance Objects in the Path Name use the
<code>{i}</code> identifier to indicate their place in the Path Name as
specified in TR-106 <span class="citation" data-cites="TR-106"><a
href="#ref-TR-106" role="doc-biblioref">[2]</a></span>.</p>
<p>The <code>obj_paths</code> field takes a list of Object Paths, either
from the Supported Data Model or the Instantiated Data Model.</p>
<p>For example, a Path Name to the <code>AssociatedDevice</code> Object
(a child of the <code>.WiFi.AccessPoint</code> Object) could be
addressed in the Supported Data Model as
<code>Device.WiFi.AccessPoint.{i}.AssociatedDevice.{i}.</code> but in
addition to this notation the omission of the final <code>{i}.</code> is
also allowed, such as
<code>Device.WiFi.AccessPoint.{i}.AssociatedDevice.</code>. Both of
these syntaxes are supported and equivalent.</p>
<p>Alternatively an Instantiated Data Model Object Path can be used as
long as the Object exists, such as
<code>Device.WiFi.AccessPoint.1.AssociatedDevice.</code>. The Agent will
use the Supported Data Model pertaining to this particular Object when
processing the Message.</p>
<p>If the Agent encounters a diverging Supported Data Model, e.g. due to
the use of different Mounted Objects underneath a Mountpoint, the Agent
will skip the traversal of the children Objects, populate the Response’s
<code>divergent_paths</code> element with all divergent Object Instance
Paths, and continue processing with the next unambiguous Object. The
Supported Data Model of such divergent Objects can only be obtained by
specifically using Object Instance Paths in the <code>obj_paths</code>
field of a GetSupportedDM request.</p>
<p>The Agent’s Response returns all Path Names in the
<code>supported_obj_path</code> field according to its Supported Data
Model.</p>
<p>To clarify the difference between an Instantiated Data Model Object
Path and a Supported Data Model Object Path:</p>
<ul>
<li>If a <code>{i}</code> is encountered in the Object Path, it cannot
be followed by an Instance Identifier.</li>
<li>If the Object Path ends with an Instance Identifier, it is treated
as an Instantiated Data Model Object Path.</li>
<li>If the Object Path contains a <code>{i}</code>, it is a Supported
Data Model Object Path.</li>
</ul>
<h4 class="auto-hoverlink" data-info="header"
id="sec:getsupporteddm-examples">7.5.3.1 GetSupportedDM Examples</h4>
<p>For example, the Controller wishes to learn the Wi-Fi capabilities
the Agent represents. It could issue a GetSupportedDM Request as:</p>
<pre data-filter="pbv" type="Request"><code>    get_supported_dm {
      obj_paths : &quot;Device.WiFi.&quot;
      first_level_only : false
      return_commands : false
      return_events : false
      return_params : false
    }</code></pre>
<p>The Agent’s Response would be:</p>
<pre data-filter="pbv" type="Response"><code>    get_supported_dm_resp {
      req_obj_results {
        req_obj_path: &quot;Device.WiFi.&quot;
        data_model_inst_uri: &quot;urn:broadband-forum-org:tr-181-2-12-0&quot;
        supported_objs {
          supported_obj_path: &quot;Device.WiFi.&quot;
          access: OBJ_READ_ONLY
          is_multi_instance: false
        }
        supported_objs {
          supported_obj_path: &quot;Device.WiFi.Radio.{i}.&quot;
          access: OBJ_READ_ONLY
          is_multi_instance: true
        }
        supported_objs {
          supported_obj_path: &quot;Device.WiFi.Radio.{i}.Stats&quot;
          access: OBJ_READ_ONLY
          is_multi_instance: false
        }
        supported_objs {
          supported_obj_path: &quot;Device.WiFi.SSID.{i}.&quot;
          access: OBJ_ADD_DELETE
          is_multi_instance: true
        }
        supported_objs {
          supported_obj_path: &quot;Device.WiFi.SSID.{i}.Stats&quot;
          access: OBJ_READ_ONLY
          is_multi_instance: false
        }
        supported_objs {
          supported_obj_path: &quot;Device.WiFi.AccessPoint.{i}.&quot;
          access: OBJ_ADD_DELETE
          is_multi_instance: true
        }
        supported_objs {
          supported_obj_path: &quot;Device.WiFi.AccessPoint.{i}.Security.&quot;
          access: OBJ_READ_ONLY
          is_multi_instance: false
        }
        supported_objs {
          supported_obj_path: &quot;Device.WiFi.AccessPoint.{i}.WPS.&quot;
          access: OBJ_READ_ONLY
          is_multi_instance: false
        }
        supported_objs {
          supported_obj_path: &quot;Device.WiFi.AccessPoint.{i}.AssociatedDevice.{i}.&quot;
          access: OBJ_READ_ONLY
          is_multi_instance: true
        }
        supported_objs {
          supported_obj_path: &quot;Device.WiFi.AccessPoint.{i}.AssociatedDevice.{i}.Stats.&quot;
          access: OBJ_READ_ONLY
          is_multi_instance: false
        }
        supported_objs {
          supported_obj_path: &quot;Device.WiFi.AccessPoint.{i}.AC.{i}.&quot;
          access: OBJ_READ_ONLY
          is_multi_instance: true
        }
        supported_objs {
          supported_obj_path: &quot;Device.WiFi.AccessPoint.{i}.AC.{i}.Stats.&quot;
          access: OBJ_READ_ONLY
          is_multi_instance: false
        }
        supported_objs {
          supported_obj_path: &quot;Device.WiFi.AccessPoint.{i}.Accounting.&quot;
          access: OBJ_READ_ONLY
          is_multi_instance: false
        }
        supported_objs {
          supported_obj_path: &quot;Device.WiFi.EndPoint.{i}.&quot;
          access: OBJ_ADD_DELETE
          is_multi_instance: true
        }

        ## And continued, for Device.WiFi.EndPoint.{i}. Sub-Objects such as Device.WiFi.EndPoint.{i}.Stats., Device.WiFi.EndPoint.{i}/// .Security., etc.

      }
    }</code></pre>
<p>In another example request:</p>
<pre data-filter="pbv" type="Request"><code>    get_supported_dm {
      obj_paths : &quot;Device.WiFi.&quot;
      first_level_only : true
      return_commands : true
      return_events : true
      return_params : true
    }</code></pre>
<p>The Agent’s response would be:</p>
<pre data-filter="pbv" type="Response"><code>    get_supported_dm_resp {
      req_obj_results {
        req_obj_path: &quot;Device.WiFi.&quot;
        data_model_inst_uri: &quot;urn:broadband-forum-org:tr-181-2-12-0&quot;
        supported_objs {
          supported_obj_path: &quot;Device.WiFi.&quot;
          access: OBJ_READ_ONLY
          is_multi_instance: false
          supported_params {
            param_name: &quot;RadioNumberOfEntries&quot;
            access: PARAM_READ_ONLY
            value_type : PARAM_UNSIGNED_INT
            value_change : VALUE_CHANGE_ALLOWED
          }
          supported_params {
            param_name: &quot;SSIDNumberOfEntries&quot;
            access: PARAM_READ_ONLY
            value_type : PARAM_UNSIGNED_INT
            value_change : VALUE_CHANGE_ALLOWED
          }

          ## Continued for all Device.WiFi. Parameters

          supported_commands {
            command_name: &quot;NeighboringWiFiDiagnostic()&quot;
            output_arg_names: &quot;Status&quot;
            output_arg_names: &quot;Result.{i}.Radio&quot;
            output_arg_names: &quot;Result.{i}.SSID&quot;
            output_arg_names: &quot;Result.{i}.BSSID&quot;
            output_arg_names: &quot;Result.{i}.Mode&quot;
            output_arg_names: &quot;Result.{i}.Channel&quot;

            ## Continued for other NeighboringWiFiDiagnostic() output arguments

            command_type : CMD_ASYNC
          }
        }

        ## followed by its immediate child objects with no details

        supported_objs {
          supported_obj_path: &quot;Device.WiFi.Radio.{i}.&quot;
          access: OBJ_READ_ONLY
          is_multi_instance: true
        }
        supported_objs {
          supported_obj_path: &quot;Device.WiFi.SSID.{i}.&quot;
          access: OBJ_ADD_DELETE
          is_multi_instance: true
        }
        supported_objs {
          supported_obj_path: &quot;Device.WiFi.AccessPoint.{i}.&quot;
          access: OBJ_ADD_DELETE
          is_multi_instance: true
        }
        supported_objs {
          supported_obj_path: &quot;Device.WiFi.EndPoint.{i}.&quot;
          access: OBJ_ADD_DELETE
          is_multi_instance: true
        }
      }
    }</code></pre>
<h4 class="auto-hoverlink" data-info="header"
id="sec:getsupporteddm-request-fields">7.5.3.2 GetSupportedDM Request
Fields</h4>
<p><code>repeated obj_paths</code></p>
<p>This field contains a repeated set of Path Names to Objects in the
Agent’s Supported or Instantiated Data Model. For Path Names from the
Supported Data Model the omission of the final <code>{i}.</code> is
allowed.</p>
<p><code>bool first_level_only</code></p>
<p>This field, if <code>true</code>, indicates that the Agent returns
only those objects matched by the Path Name or Search Path in
<code>obj_path</code> and its immediate (i.e., next level) child
objects. The list of child objects does not include commands, events, or
Parameters of the child objects regardless of the values of the
following elements:</p>
<p><code>bool return_commands</code></p>
<p>This field, if <code>true</code>, indicates that, in the
<code>supported_objs</code>, the Agent should include a
<code>supported_commands</code> field containing Commands supported by
the reported Object(s).</p>
<p><code>bool return_events</code></p>
<p>This field, if <code>true</code>, indicates that, in the
<code>supported_objs</code>, the Agent should include a
<code>supported_events</code> field containing Events supported by the
reported Object(s).</p>
<p><code>bool return_params</code></p>
<p>This field, if <code>true</code>, indicates that, in the
<code>supported_objs</code>, the Agent should include a
<code>supported_params</code> field containing Parameters supported by
the reported Object(s).</p>
<h4 class="auto-hoverlink" data-info="header"
id="sec:getsupporteddmresp-fields">7.5.3.3 GetSupportedDMResp
Fields</h4>
<p><code>repeated RequestedObjectResult req_obj_results</code></p>
<p>This field contains a repeated set of messages of type
<code>RequestedObjectResult</code>.</p>
<h5 class="auto-hoverlink" data-info="header"
id="sec:requestedobjectresult-fields">7.5.3.3.1 RequestedObjectResult
Fields</h5>
<p><code>string req_obj_path</code></p>
<p>This field contains one of the Path Names given in
<code>obj_path</code> of the associated GetSupportedDM Request.</p>
<p><code>fixed32 err_code</code></p>
<p>This field contains a numeric code (<a href="#sec:error-codes"
class="heading">Error Codes</a>) indicating the type of error that
caused the GetSupportedDM to fail on this Path Name. A value of 0
indicates the Path Name could be read successfully.</p>
<p><strong><span id="r-gsp.0"
class="auto-hoverlink">R-GSP.0</span></strong> - If the Controller
making the Request does not have Read permission on an Object or
Parameter matched through the <code>requested_path</code> field, the
Object or Parameter MUST be treated as if it is not present in the
Agent’s Supported Data Model.</p>
<p><code>string err_msg</code></p>
<p>This field contains additional information about the reason behind
the error.</p>
<p><code>string data_model_inst_uri</code></p>
<p>This field contains a Uniform Resource Identifier (URI) to the Data
Model associated with the Object specified in <code>obj_path</code>.</p>
<p><code>repeated SupportedObjectResult supported_objs</code></p>
<p>The field contains a message of type
<code>SupportedObjectResult</code> for each reported Object.</p>
<h6 class="auto-hoverlink" data-info="header"
id="sec:supportedobjectresult-fields">7.5.3.3.1.1 SupportedObjectResult
Fields</h6>
<p>In the case of a diverging Supported Data Model, only the
<code>supported_obj_path</code>, <code>access</code>,
<code>is_multi_instance</code>, and <code>divergent_paths</code> fields
will be populated for the divergent Object.</p>
<p><code>string supported_obj_path</code></p>
<p>This field contains the Full Object Path Name of the reported Object
in Supported Data Model notation.</p>
<p><code>ObjAccessType access</code></p>
<p>The field contains an enumeration of type ObjAccessType specifying
the access permissions that are specified for this Object in the Agent’s
Supported Data Model. This usually only applies to Multi-Instance
Objects. This may be further restricted to the Controller based on rules
defined in the Agent’s Access Control List. It is an enumeration of:</p>
<pre><code>    OBJ_READ_ONLY (0)
    OBJ_ADD_DELETE (1)
    OBJ_ADD_ONLY (2)
    OBJ_DELETE_ONLY (3)</code></pre>
<p><code>bool is_multi_instance</code></p>
<p>This field, if <code>true</code>, indicates that the reported Object
is a Multi-Instance Object.</p>
<p><code>repeated SupportedParamResult supported_params</code></p>
<p>The field contains a message of type
<code>SupportedParamResult</code> for each Parameter supported by the
reported Object. If there are no Parameters in the Object, this should
be an empty list.</p>
<p><code>repeated SupportedCommandResult supported_commands</code></p>
<p>The field contains a message of type
<code>SupportedCommandResult</code> for each Command supported by the
reported Object. If there are no Parameters in the Object, this should
be an empty list.</p>
<p><code>repeated SupportedEventResult supported_events</code></p>
<p>The field contains a message of type
<code>SupportedEventResult</code> for each Event supported by the
reported Object. If there are no Parameters in the Object, this should
be an empty list.</p>
<p><code>repeated string divergent_paths</code></p>
<p>The field contains an Object Instance Path for each divergent Path
Name.</p>
<p><em>Note: The <code>divergent_paths</code> field was added in USP
1.2. An Agent that supports versions before USP 1.2 would not know to
send the <code>divergent_paths</code> field and thus an empty list will
be seen by the Controller.</em></p>
<h6 class="auto-hoverlink" data-info="header"
id="sec:supportedparamresult-fields">7.5.3.3.1.2 SupportedParamResult
Fields</h6>
<p><code>string param_name</code></p>
<p>This field contains the Relative Path of the Parameter.</p>
<p><code>ParamAccessType access</code></p>
<p>The field contains an enumeration of type ParamAccessType specifying
the access permissions that are specified for this Parameter in the
Agent’s Supported Data Model. This may be further restricted to the
Controller based on rules defined in the Agent’s Access Control List. It
is an enumeration of:</p>
<pre><code>    PARAM_READ_ONLY (0)
    PARAM_READ_WRITE (1)
    PARAM_WRITE_ONLY (2)</code></pre>
<p><code>ParamValueType value_type</code></p>
<p>This field contains an enumeration of type ParamValueType specifying
the <em>primitive (or base) data type</em> of this Parameter in the
Agent’s Supported Data Model. It is an enumeration of:</p>
<pre><code>    PARAM_UNKNOWN (0)
    PARAM_BASE_64 (1)
    PARAM_BOOLEAN (2)
    PARAM_DATE_TIME (3)
    PARAM_DECIMAL (4)
    PARAM_HEX_BINARY (5)
    PARAM_INT (6)
    PARAM_LONG (7)
    PARAM_STRING (8)
    PARAM_UNSIGNED_INT (9)
    PARAM_UNSIGNED_LONG (10)</code></pre>
<p><em>Note: The value_type field was added in USP 1.2, and the
PARAM_UNKNOWN enumerated value is present for backwards compatibility
purposes. An Agent that supports versions before USP 1.2 would not know
to send the value_type and thus a 0 value (PARAM_UNKNOWN) will be seen
by the Controller.</em></p>
<p><em>Note: This refers to the data type of the Parameter as
implemented on the device, even though the value itself is transmitted
as a Protocol Buffers string.</em></p>
<p><code>ValueChangeType value_change</code></p>
<p>This field contains an enumeration of type ValueChangeType specifying
whether or not the Agent will honor or ignore a ValueChange Subscription
for this Parameter. The value of this field does not impact the ability
for a Controller to create a ValueChange Subscription that references
the associated Parameter, it only impacts how the Agent handles the
Subscription. It is an enumeration of:</p>
<pre><code>    VALUE_CHANGE_UNKNOWN (0)
    VALUE_CHANGE_ALLOWED (1)
    VALUE_CHANGE_WILL_IGNORE (2)</code></pre>
<p><em>Note: The value_change field was added in USP 1.2, and the
VALUE_CHANGE_UNKNOWN enumerated value is present for backwards
compatibility purposes. An Agent that supports versions before USP 1.2
would not know to send the value_change and thus a 0 value
(VALUE_CHANGE_UNKNOWN) will be seen by the Controller.</em></p>
<h6 class="auto-hoverlink" data-info="header"
id="sec:supportedcommandresult-fields">7.5.3.3.1.3
SupportedCommandResult Fields</h6>
<p><code>string command_name</code></p>
<p>This field contains the Relative Path of the Command.</p>
<p><code>repeated string input_arg_names</code></p>
<p>This field contains a repeated set of Relative Paths for the input
arguments of the Command, which can include Objects and Object Instances
where the names are represented in Supported Data Model notation.</p>
<p><em>Note: This field only contains the Path Name of the supported
Input arguments without details about the supported number of instances,
mandatory arguments or expected data types. Those details are
implementation specific and not detailed as part of the
<code>SupportedCommandResult</code>.</em></p>
<p><code>repeated string output_arg_names</code></p>
<p>This field contains a repeated set of Relative Paths for the output
arguments of the Command, which can include Objects and Object Instances
where the names are represented in Supported Data Model notation.</p>
<p><code>CmdType command_type</code></p>
<p>This field contains an enumeration of type CmdType specifying the
type of execution for the Command. It is an enumeration of:</p>
<pre><code>    CMD_UNKNOWN (0)
    CMD_SYNC (1)
    CMD_ASYNC (2)</code></pre>
<p><em>Note: The command_type field was added in USP 1.2, and the
CMD_UNKNOWN enumerated value is present for backwards compatibility
purposes. An Agent that supports versions before USP 1.2 would not know
to send the command_type and thus a 0 value (CMD_UNKNOWN) will be seen
by the Controller.</em></p>
<h6 class="auto-hoverlink" data-info="header"
id="sec:supportedeventresult">7.5.3.3.1.4 SupportedEventResult</h6>
<p><code>string event_name</code></p>
<p>This field contains the Relative Path of the Event.</p>
<p><code>repeated string arg_names</code></p>
<p>This field contains a repeated set of Relative Paths for the
arguments of the Event.</p>
<h4 class="auto-hoverlink" data-info="header"
id="sec:getsupporteddm-error-codes">7.5.3.4 GetSupportedDM Error
Codes</h4>
<p>Appropriate error codes for the GetSupportedDM Message include
<code>7000-7006</code>, <code>7008</code>, <code>7016</code>,
<code>7026</code>, and <code>7800-7999</code>.</p>
<p><em>Note: when using error <code>7026</code> (Invalid path), it is
important to note that in the context of GetSupportedDM this applies to
the Agent’s Supported Data Model.</em></p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:getsupportedprotocol">7.5.4 GetSupportedProtocol</h3>
<p>The GetSupportedProtocol Message is used as a simple way for the
Controller and Agent to learn which versions of USP each supports to aid
in interoperability and backwards compatibility.</p>
<h4 class="auto-hoverlink" data-info="header"
id="sec:getsupportedprotocol-request-fields">7.5.4.1
GetSupportedProtocol Request Fields</h4>
<p><code>string controller_supported_protocol_versions</code></p>
<p>A comma separated list of USP Protocol Versions (major.minor)
supported by this Controller.</p>
<h4 class="auto-hoverlink" data-info="header"
id="sec:getsupportedprotocolresponse-fields">7.5.4.2
GetSupportedProtocolResponse Fields</h4>
<p><code>string agent_supported_protocol_versions</code></p>
<p>A comma separated list of USP Protocol Versions (major.minor)
supported by this Agent.</p>
<h3 class="auto-hoverlink" data-info="header" id="sec:register">7.5.5
The Register Message</h3>
<p>The Register message is an Agent to Controller message used to
register new Service Elements.</p>
<p>See <a href="#sec:software-modularization-theory-of-operations"
class="heading">Software Modularization and USP-Enabled Applications
Theory of Operation appendix</a> for more information on when to use the
Register message.</p>
<h4 class="auto-hoverlink" data-info="header"
id="sec:register-examples">7.5.5.1 Register Examples</h4>
<p>A USP Agent can register several Service Elements with one or
multiple Register Request messages.</p>
<pre data-filter="pbv"><code>header {
  msg_id: &quot;94521&quot;
  msg_type: REGISTER
}
body {
  request {
    register {
      allow_partial: true
      reg_paths {
        path: &quot;Device.Time.&quot;
      }
      reg_paths {
        path: &quot;Device.WiFi.DataElements.&quot;
      }
    }
  }
}</code></pre>
<p>In case the registration was successful, the USP Controller will
respond with a Register Response message.</p>
<pre data-filter="pbv"><code>header {
  msg_id: &quot;94521&quot;
  msg_type: REGISTER_RESP
}
body {
  response {
    register_resp {
      registered_path_results {
        requested_path: &quot;Device.Time.&quot;
        oper_status {
          oper_success {
            registered_path: &quot;Device.Time.&quot;
          }
        }
      }

      registered_path_results {
        requested_path: &quot;Device.WiFi.DataElements.&quot;
        oper_status {
          oper_success {
            registered_path: &quot;Device.WiFi.DataElements.&quot;
          }
        }
      }
    }
  }
}</code></pre>
<p>In case the registration failed partially, because the
“Device.WiFi.DataElements.” object was already registered, the USP
Controller will respond with the following Register Response
message.</p>
<pre data-filter="pbv"><code>header {
  msg_id: &quot;94521&quot;
  msg_type: REGISTER_RESP
}
body {
  response {
    register_resp {
      registered_path_results {
        requested_path: &quot;Device.Time.&quot;
        oper_status {
          oper_success {
            registered_path: &quot;Device.Time.&quot;
          }
        }
      }

      registered_path_results {
        requested_path: &quot;Device.WiFi.DataElements.&quot;
        oper_status {
          oper_failure {
            err_code: 7029
            err_msg: &quot;Device.WiFi.DataElements. object path has already been registered&quot;
          }
        }
      }
    }
  }
}</code></pre>
<p>If <code>allow_partial</code> was set to <code>false</code> in the
Register Request and the registration failed, the USP Controller would
instead respond with a USP Error message.</p>
<pre data-filter="pbv"><code>header {
  msg_id: &quot;94521&quot;
  msg_type: ERROR
}
body {
  error {
    err_code: 7029
    err_msg: &quot;Device.WiFi.DataElements. object path has already been registered&quot;
  }
}</code></pre>
<h4 class="auto-hoverlink" data-info="header"
id="sec:register-request-fields">7.5.5.2 Register Request Fields</h4>
<p><code>bool allow_partial</code></p>
<p>The Register message contains a boolean <code>allow_partial</code> to
indicate whether the registration must succeed completely or is allowed
to fail partially. If <code>allow_partial</code> is <code>false</code>,
nothing will be registered if one of the provided paths fails to be
registered (e.g. due to an already existing registration) and the USP
Controller will respond with a USP Error message. If
<code>allow_partial</code> is <code>true</code>, the USP Controller will
try to register every path individually and will always respond with a
RegisterResp message, even if none of the requested paths can be
registered.</p>
<p><strong><span id="r-reg.0"
class="auto-hoverlink">R-REG.0</span></strong> - If the
<code>allow_partial</code> field is set to <code>true</code> and no
other exceptions are encountered, the Controller treats each of the
reg_paths independently. The Controller MUST complete the registration
of each reg_path regardless of the inability to register one of the
others.</p>
<p><strong><span id="r-reg.1"
class="auto-hoverlink">R-REG.1</span></strong> - If the
<code>allow_partial</code> field is set to <code>false</code>, and no
other exceptions are encountered, the Controller treats each of the
reg_paths holistically. A failure to handle one of the reg_paths will
cause the Register Message to fail and return an Error Message.</p>
<p><code>repeated RegistrationPath reg_paths</code></p>
<p>This field contains a repeated set of RegistrationPaths for each path
the USP Agent wants to register.</p>
<h5 class="auto-hoverlink" data-info="header"
id="sec:registrationpath-fields">7.5.5.2.1 RegistrationPath Fields</h5>
<p><code>string path</code></p>
<p>This field contains the Object Path the USP Agent wants to
register.</p>
<p><strong><span id="r-reg.2"
class="auto-hoverlink">R-REG.2</span></strong> - The path field MUST
contain an Object Path without any instance numbers. This path MUST NOT
not use the Supported Data Model notation (with {i}), meaning that it is
not allowed to register a sub-object to a multi-instance object.</p>
<h4 class="auto-hoverlink" data-info="header"
id="sec:register-response-fields">7.5.5.3 Register Response Fields</h4>
<p><code>repeated RegisteredPathResult registered_path_results</code></p>
<p>This field contains a repeated set of RegisteredPathResults for each
path the USP Agent tried to register.</p>
<h4 class="auto-hoverlink" data-info="header"
id="sec:registeredpathresult-fields">7.5.5.4 RegisteredPathResult
Fields</h4>
<p><code>string requested_path</code></p>
<p>This field contains the value of the entry of the path (in the
Register Request) associated with this RegisteredPathResult.</p>
<p><code>OperationStatus oper_status</code></p>
<p>This field contains a message of type OperationStatus.</p>
<h5 class="auto-hoverlink" data-info="header"
id="sec:operationstatus-fields-3">7.5.5.4.1 OperationStatus Fields</h5>
<p><code>oneof oper_status</code></p>
<p>This field contains a message of one of the following types.</p>
<p><code>OperationFailure oper_failure</code></p>
<p>Used when the path specified in requested_path failed to be
registered.</p>
<p><code>OperationSuccess oper_success</code></p>
<p>Used when the path specified in requested_path was successfully
registered.</p>
<h5 class="auto-hoverlink" data-info="header"
id="sec:operationfailure-fields-3">7.5.5.4.2 OperationFailure
Fields</h5>
<p><code>fixed32 err_code</code></p>
<p>This field contains a numeric code (<a href="#sec:error-codes"
class="heading">Error Codes</a>) indicating the type of error that
caused the registration to fail.</p>
<p><code>string err_msg</code></p>
<p>This field contains additional information about the reason behind
the error.</p>
<h5 class="auto-hoverlink" data-info="header"
id="sec:operationsuccess-fields-2">7.5.5.4.3 OperationSuccess
Fields</h5>
<p><code>string registered_path</code></p>
<p>This field returns the path that was registered.</p>
<h4 class="auto-hoverlink" data-info="header"
id="sec:register-message-supported-error-codes">7.5.5.5 Register Message
Supported Error Codes</h4>
<p>Appropriate error codes for the Register Message include 7000-7008,
7016, 7028-7029 and 7800-7999.</p>
<h3 class="auto-hoverlink" data-info="header" id="sec:deregister">7.5.6
The Deregister Message</h3>
<p>The Deregister message is an Agent to Controller message used to
deregister a previously registered data model at the USP Controller.
When a USP Agent terminates, all Services elements will be deregistered
automatically by the USP Controller.</p>
<p>A USP Agent can choose to deregister its Service Elements during
normal operation or when it terminates.</p>
<p><em>Note: A Deregister Request does not contain a boolean
<code>allow_partial</code>, but the Controller will handle each path in
the Deregister Request individually. In other words,
<code>allow_partial</code> is implicitly set to <code>true</code> during
the deregistration. The USP Controller will provide information about
the success or failure to deregister each requested path in the
Deregister Response message.</em></p>
<h4 class="auto-hoverlink" data-info="header"
id="sec:deregister-examples">7.5.6.1 Deregister Examples</h4>
<p>A USP Agent can deregister several Service Elements with a Deregister
Request message.</p>
<pre data-filter="pbv"><code>header {
  msg_id: &quot;94522&quot;
  msg_type: DEREGISTER
}
body {
  request {
    deregister {
      paths: &quot;Device.Time.&quot;
      paths: &quot;Device.WiFi.DataElements.&quot;
    }
  }
}</code></pre>
<p>In case the deregistration was successful, the USP Controller will
respond with a Deregister Response message.</p>
<pre data-filter="pbv"><code>header {
  msg_id: &quot;94522&quot;
  msg_type: DEREGISTER_RESP
}
body {
  response {
    deregister_resp {
      deregistered_path_results {
        requested_path: &quot;Device.Time.&quot;
        oper_status {
          oper_success {
            deregistered_path: &quot;Device.Time.&quot;
          }
        }
      }

      deregistered_path_results {
        requested_path: &quot;Device.WiFi.DataElements.&quot;
        oper_status {
          oper_success {
            deregistered_path: &quot;Device.WiFi.DataElements.&quot;
          }
        }
      }
    }
  }
}</code></pre>
<h4 class="auto-hoverlink" data-info="header"
id="sec:deregister-request-fields">7.5.6.2 Deregister Request
Fields</h4>
<p><code>repeated string paths</code></p>
<p>This field contains a set of paths that the USP Agent wants to
deregister.</p>
<p><strong><span id="r-dereg.1"
class="auto-hoverlink">R-DEREG.1</span></strong> - A USP Agent MUST
<em>only</em> deregister Service Elements that it registered with a
previous Register message.</p>
<p><strong><span id="r-dereg.2"
class="auto-hoverlink">R-DEREG.2</span></strong> - An empty path field
MUST be interpreted to deregister all Service Elements belonging to the
USP Agent.</p>
<p><strong><span id="r-dereg.3"
class="auto-hoverlink">R-DEREG.3</span></strong> - A USP Agent MAY
deregister one or more Service Elements with one Deregister Request
message containing multiple path fields.</p>
<p><em>Note: The path field contains an Object Path without any instance
numbers. This path doesn’t contain any sub-objects to a multi-instance
object.</em></p>
<h4 class="auto-hoverlink" data-info="header"
id="sec:deregister-response-fields">7.5.6.3 Deregister Response
Fields</h4>
<p><code>repeated DeregisteredPathResult deregistered_path_results</code></p>
<p>This field contains a repeated set of DeregisteredPathResults for
each path the USP Agent tried to deregister.</p>
<p><strong><span id="r-dereg.4"
class="auto-hoverlink">R-DEREG.4</span></strong> - A USP Controller MUST
always respond with a Deregister Response message to a Deregister
Request. USP Error messages are not used.</p>
<h4 class="auto-hoverlink" data-info="header"
id="sec:deregisteredpathresult-fields">7.5.6.4 DeregisteredPathResult
Fields</h4>
<p><code>string requested_path</code></p>
<p>This field contains the value of the entry of the path (in the
Deregister Request) associated with this DeregisteredPathResult.</p>
<p><code>OperationStatus oper_status</code></p>
<p>This field contains a message of type OperationStatus.</p>
<h5 class="auto-hoverlink" data-info="header"
id="sec:operationstatus-fields-4">7.5.6.4.1 OperationStatus Fields</h5>
<p><code>oneof oper_status</code></p>
<p>This field contains a message of one of the following types.</p>
<p><code>OperationFailure oper_failure</code></p>
<p>Used when the path specified in requested_path failed to be
deregistered.</p>
<p><code>OperationSuccess oper_success</code></p>
<p>Used when the path specified in requested_path was successfully
deregistered.</p>
<h5 class="auto-hoverlink" data-info="header"
id="sec:operationfailure-fields-4">7.5.6.4.2 OperationFailure
Fields</h5>
<p><code>fixed32 err_code</code></p>
<p>This field contains a numeric code (<a href="#sec:error-codes"
class="heading">Error Codes</a>) indicating the type of error that
caused the deregistration to fail.</p>
<p><code>string err_msg</code></p>
<p>This field contains additional information about the reason behind
the error.</p>
<h5 class="auto-hoverlink" data-info="header"
id="sec:operationsuccess-fields-3">7.5.6.4.3 OperationSuccess
Fields</h5>
<p><code>string deregistered_path</code></p>
<p>This field returns the path that was deregistered.</p>
<h4 class="auto-hoverlink" data-info="header"
id="sec:deregister-message-supported-error-codes">7.5.6.5 Deregister
Message Supported Error Codes</h4>
<p>Appropriate error codes for the Deregister Message include 7000-7008,
7016, 7030 and 7800-7999.</p>
<h2 class="auto-hoverlink" data-info="header"
id="sec:notifications-and-subscriptions">7.6 Notifications and
Subscription Mechanism</h2>
<p>A Controller can use the Subscription mechanism to subscribe to
certain events that occur on the Agent, such as a Parameter change,
Object removal, wake-up, etc. When such event conditions are met, the
Agent may either send a <a href="#sec:notify" class="heading">Notify
Message</a> to the Controller, update its own configuration, or perform
both actions depending on the Subscription’s configuration.</p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:using-subscription-objects">7.6.1 Using Subscription
Objects</h3>
<p>Subscriptions are maintained in instances of the Multi-Instance
Subscription Object in the USP data model. The normative requirements
for these Objects are described in the data model Parameter descriptions
for <code>Device.LocalAgent.Subscription.{i}.</code> in the Device:2
Data Model <span class="citation" data-cites="TR-181"><a
href="#ref-TR-181" role="doc-biblioref">[3]</a></span>.</p>
<p><strong><span id="r-not.0"
class="auto-hoverlink">R-NOT.0</span></strong> - The Agent and
Controller MUST follow the normative requirements defined in the
<code>Device.LocalAgent.Subscription.{i}.</code> Object specified in the
Device:2 Data Model <span class="citation" data-cites="TR-181"><a
href="#ref-TR-181" role="doc-biblioref">[3]</a></span>.</p>
<p><strong><span id="r-not.0a"
class="auto-hoverlink">R-NOT.0a</span></strong> - When considering the
time needed to make a state change and trigger a Notification, an
implementation SHOULD make changes to its state and initiate a
Notification with a window no longer than 10 seconds.</p>
<p><em>Note: Those familiar with Broadband Forum TR-069 <span
class="citation" data-cites="TR-069"><a href="#ref-TR-069"
role="doc-biblioref">[1]</a></span> will recall that a notification for
a value change caused by an Auto-Configuration Server (ACS - the CWMP
equivalent of a Controller) are not sent to the ACS. Since there is only
a single ACS notifying the ACS of value changes it requested is
unnecessary. This is not the case in USP: an Agent should follow the
behavior specified by a subscription, regardless of the originator of
that subscription.</em></p>
<h4 class="auto-hoverlink" data-info="header"
id="sec:referencelist-parameter">7.6.1.1 ReferenceList Parameter</h4>
<p>All subscriptions apply to one or more Objects or Parameters in the
Agent’s Instantiated Data Model. These are specified as Path Names or
Search Paths in the <code>ReferenceList</code> Parameter. The
<code>ReferenceList</code> Parameter may have different meaning
depending on the nature of the notification subscribed to.</p>
<p>For example, a Controller wants to be notified when a new Wi-Fi
station joins the Wi-Fi network. It uses the Add Message to create an
instance of a Subscription Object with
<code>Device.WiFi.AccessPoint.1.AssociatedDevice.</code> specified in
the <code>ReferenceList</code> Parameter and <code>ObjectCreation</code>
as the <code>NotificationType</code>.</p>
<p>In another example, a Controller wants to be notified whenever an
outside source changes the SSID of a Wi-Fi network. It uses the Add
Message to create an instance of a Subscription Object with
<code>Device.WiFi.SSID.1.SSID</code> specified in the
<code>ReferenceList</code> and <code>ValueChange</code> as the
<code>NotificationType</code>.</p>
<h4 class="auto-hoverlink" data-info="header"
id="sec:triggeraction-parameter">7.6.1.2 TriggerAction Parameter</h4>
<p>Subscriptions can be used to define the actions to be performed by
the Agent when an event occurs. This is defined in the
<code>TriggerAction</code> Parameter. The default is for the Agent to
send a <a href="#sec:notify" class="heading">Notify Message</a>, but it
could also perform an update of its own configuration, or both sending
the Notify and performing the configuration.</p>
<p>For example, an Agent may be configure with a Subscription for the
<code>Device.LocalAgent.Threshold.{i}.Triggered!</code> event such that
when it occurs the Agent both sends a Notify message and configures the
<code>Device.BulkData.Profile.{i}.Enable</code> to start sending BukData
reports (if defined to do so in the <code>TriggerConfigSettings</code>
Parameter of the Subscription).</p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:responses-and-retry">7.6.2 Responses to Notifications and
Notification Retry</h3>
<p>The Notify request contains a flag, <code>send_resp</code>, that
specifies whether or not the Controller should send a response Message
after receiving a Notify request. This is used in tandem with the
<code>NotifRetry</code> Parameter in the subscription Object - if
<code>NotifRetry</code> is <code>true</code>, then the Agent sends its
Notify requests with <code>send_resp : true</code>, and the Agent
considers the notification delivered when it receives a response from
the Controller. If <code>NotifRetry</code> is <code>false</code>, the
Agent does not need to use the <code>send_resp</code> flag and should
ignore the delivery state of the notification.</p>
<p>If <code>NotifRetry</code> is <code>true</code>, and the Agent does
not receive a response from the Controller, it begins retrying using the
retry algorithm below. The subscription Object also uses a
<code>NotifExpiration</code> Parameter to specify when this retry should
end if no success is ever achieved.</p>
<p><strong><span id="r-not.1"
class="auto-hoverlink">R-NOT.1</span></strong> - When retrying
notifications, the Agent MUST use the following retry algorithm to
manage the retransmission of the Notify request.</p>
<p>The retry interval range is controlled by two Parameters, the minimum
wait interval and the interval multiplier, each of which corresponds to
a data model Parameter, and which are described in the table below. The
factory default values of these Parameters MUST be the default values
listed in the Default column. They MAY be changed by a Controller with
the appropriate permissions at any time.</p>
<table>
<colgroup>
<col style="width: 26%" />
<col style="width: 18%" />
<col style="width: 21%" />
<col style="width: 34%" />
</colgroup>
<thead>
<tr class="header">
<th style="text-align: right;">Descriptive Name</th>
<th style="text-align: center;">Symbol</th>
<th style="text-align: center;">Default</th>
<th style="text-align: left;">Data Model Parameter Name</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: right;">Minimum wait interval</td>
<td style="text-align: center;">m</td>
<td style="text-align: center;">5 seconds</td>
<td
style="text-align: left;"><code>Device.LocalAgent.Controller.{i}.USPNotifRetryMinimumWaitInterval</code></td>
</tr>
<tr class="even">
<td style="text-align: right;">Interval multiplier</td>
<td style="text-align: center;">k</td>
<td style="text-align: center;">2000</td>
<td
style="text-align: left;"><code>Device.LocalAgent.Controller.{i}.USPNotifRetryIntervalMultiplier</code></td>
</tr>
</tbody>
</table>
<table>
<colgroup>
<col style="width: 29%" />
<col style="width: 29%" />
<col style="width: 40%" />
</colgroup>
<thead>
<tr class="header">
<th style="text-align: right;">Retry Count</th>
<th style="text-align: center;">Default Wait Interval Range (min-max
seconds)</th>
<th style="text-align: left;">Actual Wait Interval Range (min-max
seconds)</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: right;">#1</td>
<td style="text-align: center;">5-10</td>
<td style="text-align: left;">m - m.(k/1000)</td>
</tr>
<tr class="even">
<td style="text-align: right;">#2</td>
<td style="text-align: center;">10-20</td>
<td style="text-align: left;">m.(k/1000) - m.(k/1000)^2</td>
</tr>
<tr class="odd">
<td style="text-align: right;">#3</td>
<td style="text-align: center;">20-40</td>
<td style="text-align: left;">m.(k/1000)^2 - m.(k/1000)^3</td>
</tr>
<tr class="even">
<td style="text-align: right;">#4</td>
<td style="text-align: center;">40-80</td>
<td style="text-align: left;">m.(k/1000)^3 - m.(k/1000)^4</td>
</tr>
<tr class="odd">
<td style="text-align: right;">#5</td>
<td style="text-align: center;">80-160</td>
<td style="text-align: left;">m.(k/1000)^4 - m.(k/1000)^5</td>
</tr>
<tr class="even">
<td style="text-align: right;">#6</td>
<td style="text-align: center;">160-320</td>
<td style="text-align: left;">m.(k/1000)^5 - m.(k/1000)^6</td>
</tr>
<tr class="odd">
<td style="text-align: right;">#7</td>
<td style="text-align: center;">320-640</td>
<td style="text-align: left;">m.(k/1000)^6 - m.(k/1000)^7</td>
</tr>
<tr class="even">
<td style="text-align: right;">#8</td>
<td style="text-align: center;">640-1280</td>
<td style="text-align: left;">m.(k/1000)^7 - m.(k/1000)^8</td>
</tr>
<tr class="odd">
<td style="text-align: right;">#9</td>
<td style="text-align: center;">1280-2560</td>
<td style="text-align: left;">m.(k/1000)^8 - m.(k/1000)^9</td>
</tr>
<tr class="even">
<td style="text-align: right;">#10 and subsequent</td>
<td style="text-align: center;">2560-5120</td>
<td style="text-align: left;">m.(k/1000)^9 - m.(k/1000)^10</td>
</tr>
</tbody>
</table>
<p><strong><span id="r-not.2"
class="auto-hoverlink">R-NOT.2</span></strong> - Beginning with the
tenth retry attempt, the Agent MUST choose from the fixed maximum range.
The Agent will continue to retry a failed notification until it is
successfully delivered or until the <code>NotifExpiration</code> time is
reached.</p>
<p><strong><span id="r-not.3"
class="auto-hoverlink">R-NOT.3</span></strong> - Once a notification is
successfully delivered, the Agent MUST reset the retry count to zero for
the next notification Message.</p>
<p><strong><span id="r-not.4"
class="auto-hoverlink">R-NOT.4</span></strong> - If a reboot of the
Agent occurs, the Agent MUST reset the retry count to zero for the next
notification Message.</p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:notification-types">7.6.3 Notification Types</h3>
<p>There are several types events that can cause a Notify request. These
include those that deal with changes to the Agent’s Instantiated Data
Model (<code>ValueChange</code>, <code>ObjectCreation</code>,
<code>ObjectDeletion</code>), the completion of an asynchronous
Object-defined operation (<code>OperationComplete</code>), a
policy-defined <code>OnBoardRequest</code>, and a generic
<code>Event</code> for use with Object-defined events.</p>
<h4 class="auto-hoverlink" data-info="header"
id="sec:valuechange">7.6.3.1 ValueChange</h4>
<p>The <code>ValueChange</code> notification is subscribed to by a
Controller when it wants to know that the value of a single or set of
Parameters has changed from the state it was in at the time of the
subscription or to a state as described in an expression, and then each
time it transitions from then on for the life of the subscription. It is
triggered when the defined change occurs, even if it is caused by the
originating Controller.</p>
<h4 class="auto-hoverlink" data-info="header"
id="sec:objectcreation-and-objectdeletion">7.6.3.2 ObjectCreation and
ObjectDeletion</h4>
<p>These notifications are used for when an instance of the subscribed
to Multi-Instance Objects is added or removed from the Agent’s
Instantiated Data Model. Like <code>ValueChange</code>, this
notification is triggered even if the subscribing Controller is the
originator of the creation or deletion or the instance was created or
deleted implicitly, e.g. due to a configuration or status change or
indirectly via an unrelated USP Message.</p>
<p>The <code>ObjectCreation</code> notification also includes the
Object’s Unique Key Parameters and their values.</p>
<h4 class="auto-hoverlink" data-info="header"
id="sec:operationcomplete">7.6.3.3 OperationComplete</h4>
<p>The <code>OperationComplete</code> notification is used to indicate
that an asynchronous Object-defined operation finished (either
successfully or unsuccessfully). These operations may also trigger other
Events defined in the data model (see below).</p>
<h4 class="auto-hoverlink" data-info="header"
id="sec:onboardrequest">7.6.3.4 OnBoardRequest</h4>
<p>An <code>OnBoardRequest</code> notification is used by the Agent when
it is triggered by an external source to initiate the request in order
to communicate with a Controller that can provide on-boarding procedures
and communicate with that Controller (likely for the first time).</p>
<p><strong><span id="r-not.5"
class="auto-hoverlink">R-NOT.5</span></strong> - An Agent MUST send an
<code>OnBoardRequest</code> notify request in the following
circumstances:</p>
<ol type="1">
<li><p>When the <code>SendOnBoardRequest()</code> command is executed.
This sends the notification request to the Controller that is the
subject of that operation. The <code>SendOnBoardRequest()</code>
operation is defined in the Device:2 Data Model <span class="citation"
data-cites="TR-181"><a href="#ref-TR-181"
role="doc-biblioref">[3]</a></span>. This requirement applies only to
those Controller table instances that have their <code>Enabled</code>
Parameter set to <code>true</code>.</p></li>
<li><p>When instructed to do so by internal application policy (for
example, when using DHCP discovery defined above).</p></li>
</ol>
<p><em>Note: as defined in the Subscription table, OnBoardRequest is not
included as one of the enumerated types of a Subscription, i.e., it is
not intended to be the subject of a Subscription.</em></p>
<p><strong><span id="r-not.6"
class="auto-hoverlink">R-NOT.6</span></strong> If a response is
required, the OnBoardRequest MUST follow the Retry logic defined
above.</p>
<h4 class="auto-hoverlink" data-info="header" id="sec:event">7.6.3.5
Event</h4>
<p>The <code>Event</code> notification is used to indicate that an
Object-defined event was triggered on the Agent. These events are
defined in the data model and include what Parameters, if any, are
returned as part of the notification.</p>
<h3 class="auto-hoverlink" data-info="header" id="sec:notify">7.6.4 The
Notify Message</h3>
<h4 class="auto-hoverlink" data-info="header"
id="sec:notify-examples">7.6.4.1 Notify Examples</h4>
<p>In this example, a Controller has subscribed to be notified of
changes in value to the <code>Device.DeviceInfo.FriendlyName</code>
Parameter. When it is changed, the Agent sends a Notify Request to
inform the Controller of the change.</p>
<pre data-filter="pbv"><code>header {
  msg_id: &quot;33936&quot;
  msg_type: NOTIFY
}
body {
  request {
    notify {
      subscription_id: &quot;vc-1&quot;
      send_resp: true
      value_change {
          param_path: &quot;Device.DeviceInfo.FriendlyName&quot;
          param_value: &quot;MyDevicesFriendlyName&quot;
      }
    }
  }
}</code></pre>
<pre data-filter="pbv"><code>header {
  msg_id: &quot;33936&quot;
  msg_type: NOTIFY_RESP
}
body {
  response {
    notify_resp {
      subscription_id: &quot;vc-1&quot;
    }
  }
}</code></pre>
<p>In another example, the event “Boot!”, defined in the
<code>Device.</code> Object, is triggered. The Agent sends a Notify
Request to the Controller(s) subscribed to that event.</p>
<pre data-filter="pbv"><code>header {
  msg_id: &quot;26732&quot;
  msg_type: NOTIFY
}
body {
  request {
    notify {
      subscription_id: &quot;boot-1&quot;
      send_resp: true
      event {
        obj_path: &quot;Device.&quot;
        event_name: &quot;Boot!&quot;
        params {
          key: &quot;Cause&quot;
          value: &quot;LocalReboot&quot;
        }
        params {
          key: &quot;CommandKey&quot;
          value: &quot;controller-command-key&quot;
        }
        params {
          key: &quot;ParameterMap&quot;
          value: &#39;{&quot;Device.LocalAgent.Controller.1.Enable&quot;:&quot;True&quot;,&quot;Device.LocalAgent.Controller.2.Enable&quot;:&quot;False&quot;}&#39;
        }
        params {
          key: &quot;FirmwareUpdated&quot;
          value: &quot;false&quot;
        }
      }
    }
  }
}</code></pre>
<pre data-filter="pbv"><code>header {
  msg_id: &quot;26732&quot;
  msg_type: NOTIFY_RESP
}
body {
  response {
    notify_resp {
      subscription_id: &quot;boot-1&quot;
    }
  }
}</code></pre>
<h4 class="auto-hoverlink" data-info="header"
id="sec:notify-request-fields">7.6.4.2 Notify Request Fields</h4>
<p><code>string subscription_id</code></p>
<p>This field contains the locally unique opaque identifier that was set
by the Controller when it created the Subscription on the Agent.</p>
<p><strong><span id="r-not.7"
class="auto-hoverlink">R-NOT.7</span></strong> - The
<code>subscription_id</code> field MUST contain the Subscription ID of
the Subscription Object that triggered this notification. If no
subscription_id is available (for example, for OnBoardRequest
notifications), this field MUST be set to an empty string.</p>
<p><code>bool send_resp</code></p>
<p>This field lets the Agent indicate to the Controller whether or not
it expects a response in association with the Notify request.</p>
<p><strong><span id="r-not.8"
class="auto-hoverlink">R-NOT.8</span></strong> - When
<code>send_resp</code> is set to false, the Controller SHOULD NOT send a
response or error to the Agent. If a response is still sent, the
responding Controller MUST expect that any such response will be
ignored.</p>
<p><code>oneof notification</code></p>
<p>Contains one of the following Notification messages:</p>
<pre><code>Event   event
ValueChange value_change
ObjectCreation obj_creation
ObjectDeletion obj_deletion
OperationComplete oper_complete
OnBoardRequest on_board_req</code></pre>
<h5 class="auto-hoverlink" data-info="header"
id="sec:event-fields">7.6.4.2.1 Event Fields</h5>
<p><code>string obj_path</code></p>
<p>This field contains the Object or Object Instance Path of the Object
that caused this event (for example,
<code>Device.LocalAgent.</code>).</p>
<p><code>string event_name</code></p>
<p>This field contains the name of the Object defined event that caused
this notification (for example, <code>Boot!</code>).</p>
<p><code>map&lt;string, string&gt; parameters</code></p>
<p>This field contains a set of key/value pairs of Parameters associated
with this event. Refer to <a href="#sec:parameter-value-encoding"
class="heading">Parameter and Argument Value Encoding</a> for details of
how Parameter values are encoded as Protocol Buffers v3 strings.</p>
<h5 class="auto-hoverlink" data-info="header"
id="sec:valuechange-fields">7.6.4.2.2 ValueChange Fields</h5>
<p><code>string param_path</code></p>
<p>This field contains the Path Name of the changed Parameter.</p>
<p><code>string param_value</code></p>
<p>This field contains the value of the Parameter specified in
<code>param_path</code>. Refer to <a
href="#sec:parameter-value-encoding" class="heading">Parameter and
Argument Value Encoding</a> for details of how Parameter values are
encoded as Protocol Buffers v3 strings.</p>
<h5 class="auto-hoverlink" data-info="header"
id="sec:objectcreation-fields">7.6.4.2.3 ObjectCreation Fields</h5>
<p><code>string obj_path</code></p>
<p>This field contains the Path Name of the created Object Instance.</p>
<p><code>map&lt;string, string&gt; unique_keys</code></p>
<p>This field contains a map of key/value pairs for all of this Object’s
Unique Key Parameters that are supported by the Agent.</p>
<h5 class="auto-hoverlink" data-info="header"
id="sec:objectdeletion-fields">7.6.4.2.4 ObjectDeletion Fields</h5>
<p><code>string obj_path</code></p>
<p>This field contains the Path Name of the deleted Object Instance.</p>
<h5 class="auto-hoverlink" data-info="header"
id="sec:operationcomplete-fields">7.6.4.2.5 OperationComplete
Fields</h5>
<p><code>string command_name</code></p>
<p>This field contains the Relative Path of the Object defined command
that caused this notification (i.e., <code>Download()</code>).</p>
<p><code>string obj_path</code></p>
<p>This field contains the Object or Object Instance Path to the Object
that contains this operation.</p>
<p><code>string command_key</code></p>
<p>This field contains the command key set during an Object defined
Operation that caused this notification.</p>
<p><code>oneof operation_resp</code></p>
<p>Contains one of the following messages:</p>
<pre><code>OutputArgs req_output_args
CommandFailure cmd_failure</code></pre>
<h6 class="auto-hoverlink" data-info="header"
id="sec:outputargs-fields">7.6.4.2.5.1 OutputArgs Fields</h6>
<p><code>map&lt;string, string&gt; output_args</code></p>
<p>This field contains a map of key/value pairs indicating the output
arguments (relative to the command specified in the
<code>command_name</code> field) returned by the method invoked in the
Operate Message. Refer to <a href="#sec:parameter-value-encoding"
class="heading">Parameter and Argument Value Encoding</a> for details of
how argument values are encoded as Protocol Buffers v3 strings.</p>
<h6 class="auto-hoverlink" data-info="header"
id="sec:commandfailure-fields">7.6.4.2.5.2 CommandFailure Fields</h6>
<p><code>fixed32 err_code</code></p>
<p>This field contains a numeric code (see <a href="#sec:error-codes"
class="heading">Error Codes</a>) indicating the type of the error that
caused the operation to fail. Appropriate error codes for CommandFailure
include <code>7002-7008</code>, <code>7016</code>, <code>7022</code>,
<code>7023</code>, and <code>7800-7999</code>. Error <code>7023</code>
is reserved for asynchronous operations that were canceled by a
Controller invoking the Cancel() command on the appropriate Request
Object (see <a href="#sec:asynchronous-operations"
class="heading">Asynchronous Operations</a>).</p>
<p><code>string err_msg</code></p>
<p>This field contains additional (human readable) information about the
reason behind the error.</p>
<h5 class="auto-hoverlink" data-info="header"
id="sec:onboardrequest-fields">7.6.4.2.6 OnBoardRequest Fields</h5>
<p><code>string oui</code></p>
<p>This field contains the Organizationally Unique Identifier associated
with the Agent.</p>
<p><code>string product_class</code></p>
<p>This field contains a string used to provide additional context about
the Agent.</p>
<p><code>string serial_number</code></p>
<p>This field contains a string used to provide additional context about
the Agent.</p>
<p><code>string agent_supported_protocol_versions</code></p>
<p>A comma separated list of USP Protocol Versions (major.minor)
supported by this Agent.</p>
<h4 class="auto-hoverlink" data-info="header"
id="sec:notify-response-fields">7.6.4.3 Notify Response Fields</h4>
<p><code>string subscription_id</code></p>
<p>This field contains the Subscription ID that was received with the
Notify Request.</p>
<p><strong><span id="r-not.9"
class="auto-hoverlink">R-NOT.9</span></strong> -The Agent SHOULD ignore
the subscription_id field.</p>
<p><em>Note: The requirement in the previous versions of the
specification requiring the Agent to check this subscription_id field
has been deprecated. However for backward compatibility the Controller
is still required to send the matching subscription_id.</em></p>
<p><strong><span id="r-not.10"
class="auto-hoverlink">R-NOT.10</span></strong> - The Controller MUST
populate the subscription_id field with the same Subscription ID as was
presented in the Notify Request.</p>
<h4 class="auto-hoverlink" data-info="header"
id="sec:notify-error-codes">7.6.4.4 Notify Error Codes</h4>
<p>Appropriate error codes for the Notify Message include
<code>7000-7006</code>, and <code>7800-7999</code>.</p>
<h2 class="auto-hoverlink" data-info="header"
id="sec:defined-operations-mechanism">7.7 Defined Operations
Mechanism</h2>
<p>Additional methods (operations) are and can be defined in the USP
data model. Operations are generally defined on an Object, using the
“command” attribute, as defined in <span class="citation"
data-cites="TR-106"><a href="#ref-TR-106"
role="doc-biblioref">[2]</a></span>. The mechanism is controlled using
the <a href="#sec:operate" class="heading">Operate Message</a> in
conjunction with the Multi-Instance Request Object.</p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:synchronous-operations">7.7.1 Synchronous Operations</h3>
<p>A synchronous operation is intended to complete immediately following
its processing. When complete, the output arguments are sent in the
Operate response. If the <code>send_resp</code> flag is false, the
Controller doesn’t need the returned information (if any), and the Agent
does not send an Operate Response.</p>
<figure id="fig:operate-message-flow-for-synchronous-operations">
<img src="messages/synchronous_operation.png"
id="img:operate-message-flow-for-synchronous-operations"
alt="Operate Message Flow for Synchronous Operations" />
<figcaption><div class="auto-hoverlink"
data-anchor="fig:operate-message-flow-for-synchronous-operations">
Figure 17: Operate Message Flow for Synchronous Operations
</div></figcaption>
</figure>
<h3 class="auto-hoverlink" data-info="header"
id="sec:asynchronous-operations">7.7.2 Asynchronous Operations</h3>
<p>An asynchronous operation expects to take some processing on the
system the Agent represents and will return results at a later time.
When complete, the output arguments are sent in a <code>Notify</code>
(<code>OperationComplete</code>) request to any Controllers that have an
active subscription to the operation and Object(s) to which it
applies.</p>
<p>When a Controller using the Operate request specifies an operation
that is defined as asynchronous, the Agent creates an instance of the
Request Object in its data model, and includes a reference to the
created Object in the Operate response. If the <code>send_resp</code>
flag is <code>false</code>, the Controller doesn’t need the Request
details, and intends to ignore it.</p>
<p>The lifetime of a Request Object expires when the operation is
complete (either by success or failure). An expired Request Object is
removed from the Instantiated Data Model.</p>
<p><strong><span id="r-opr.0"
class="auto-hoverlink">R-OPR.0</span></strong> - When an Agent receives
an Operate Request that addresses an asynchronous operation, it MUST
create a Request Object in the Request table of its Instantiated Data
Model (see the Device:2 Data Model <span class="citation"
data-cites="TR-181"><a href="#ref-TR-181"
role="doc-biblioref">[3]</a></span>). When the Operation is complete
(either success or failure), it MUST remove this Object from the Request
table.</p>
<p>If any Controller wants a notification that an operation has
completed, it creates a Subscription Object with the
<code>NotificationType</code> set to <code>OperationComplete</code> and
with the <code>ReferenceList</code> Parameter including a Path Name to
the specified command. The Agent processes this Subscription when the
operation completes and sends a Notify Message, including the
<code>command_key</code> value that the Controller assigned when making
the Operate request.</p>
<p>A Controller can cancel a request that is still present in the
Agent’s <code>Device.LocalAgent.Request.</code> table by invoking the
<code>Device.LocalAgent.Request.{i}.Cancel()</code> command through
another Operate Message.</p>
<figure id="fig:operate-message-flow-for-asynchronous-operations">
<img src="messages/asynchronous_operation.png"
id="img:operate-message-flow-for-asynchronous-operations"
alt="Operate Message Flow for Asynchronous Operations" />
<figcaption><div class="auto-hoverlink"
data-anchor="fig:operate-message-flow-for-asynchronous-operations">
Figure 18: Operate Message Flow for Asynchronous Operations
</div></figcaption>
</figure>
<h4 class="auto-hoverlink" data-info="header"
id="sec:persistance-of-asynchronous-operations">7.7.2.1 Persistance of
Asynchronous Operations</h4>
<p>Synchronous Operations do not persist across a reboot or restart of
the Agent or its underlying system. It is expected that Asynchronous
Operations do not persist, and a command that is in process when the
Agent is rebooted can be expected to be removed from the Request table,
and is considered to have failed. If a command is allowed or expected to
be retained across a reboot, it will be noted in the command
description.</p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:operate-requests-on-multiple-objects">7.7.3 Operate Requests on
Multiple Objects</h3>
<p>Since the Operate request can take a Path Name expression as a value
for the command field, it is possible to invoke the same operation on
multiple valid Objects as part of a single Operate request. Responses to
requests to Operate on more than one Object are handled using the
<code>OperationResult</code> field type, which is returned as a repeated
set in the Operate Response. The success or failure of the operation on
each Object is handled separately and returned in a different
<code>OperationResult</code> entry. For this reason, operation failures
are never conveyed in an Error Message - in reply to an Operate request,
Error is only used when the Message itself fails for one or more
reasons, rather than the operation invoked.</p>
<p><em>Note: This specification does not make any requirement on the
order in which commands on multiple objects selected with a Path Name
expression are executed.</em></p>
<p><strong><span id="r-opr.1"
class="auto-hoverlink">R-OPR.1</span></strong> - When processing Operate
Requests on multiple Objects, an Agent MUST NOT send an Error Message
due to a failed operation. It MUST instead include the failure in the
<code>cmd_failure</code> field of the Operate response.</p>
<p><strong><span id="r-opr.2"
class="auto-hoverlink">R-OPR.2</span></strong> - For asynchronous
operations the Agent MUST create a separate Request Object for each
Object and associated operation matched in the command field.</p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:event-notifications-for-operations">7.7.4 Event Notifications
for Operations</h3>
<p>When an operation triggers an Event notification, the Agent sends the
Event notification for all subscribed recipients as described in <a
href="#sec:notifications-and-subscriptions"
class="heading">Notifications and Subscription Mechanism</a>.</p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:concurrent-operations">7.7.5 Concurrent Operations</h3>
<p>If an asynchronous operation is triggered multiple times by one or
more Controllers, the Agent has the following options:</p>
<ol type="1">
<li>Deny the new operation (with, for example,
<code>7005 Resources Exceeded</code> )</li>
<li>The operations are performed in parallel and independently.</li>
<li>The operations are queued and completed in order.</li>
</ol>
<p><strong><span id="r-opr.3"
class="auto-hoverlink">R-OPR.3</span></strong> - When handling
concurrently invoked operations, an Agent MUST NOT cancel an operation
already in progress unless explicitly told to do so by a Controller with
permission to do so (i.e., via the
<code>Device.LocalAgent.Request.{i}.Cancel()</code> operation).</p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:operate-examples">7.7.6 Operate Examples</h3>
<p>In this example, the Controller requests that the Agent initiate the
SendOnBoardRequest() operation defined in the
<code>Device.LocalAgent.Controller.</code> Object.</p>
<pre data-filter="pbv"><code>header {
  msg_id: &quot;42314&quot;
  msg_type: OPERATE
}
body {
  request {
    operate {
      command: &#39;Device.LocalAgent.Controller.[EndpointID==&quot;controller&quot;].SendOnBoardRequest()&#39;
      command_key: &quot;onboard_command_key&quot;
      send_resp: true
    }
  }
}</code></pre>
<pre data-filter="pbv"><code>header {
  msg_id: &quot;42314&quot;
  msg_type: OPERATE_RESP
}
body {
  response {
    operate_resp {
      operation_results {
        executed_command: &quot;Device.SelfTestDiagnostics()&quot;
        req_obj_path: &quot;Device.LocalAgent.Request.1&quot;
      }
    }
  }
}</code></pre>
<h3 class="auto-hoverlink" data-info="header" id="sec:operate">7.7.7 The
Operate Message</h3>
<h4 class="auto-hoverlink" data-info="header"
id="sec:operate-request-fields">7.7.7.1 Operate Request Fields</h4>
<p><code>string command</code></p>
<p>This field contains a Command Path or Search Path to an Object
defined Operation in one or more Objects.</p>
<p><code>string command_key</code></p>
<p>This field contains a string used as a reference by the Controller to
match the operation with notifications.</p>
<p><code>bool send_resp</code></p>
<p>This field lets the Controller indicate to Agent whether or not it
expects a response in association with the operation request.</p>
<p><strong><span id="r-opr.4"
class="auto-hoverlink">R-OPR.4</span></strong> - When
<code>send_resp</code> is set to <code>false</code>, the target Endpoint
SHOULD NOT send an <code>OperateResp</code> Message to the source
Endpoint. If an error occurs during the processing of an
<code>Operate</code> Message, the target Endpoint SHOULD send an
<code>Error</code> Message to the source Endpoint. If a response is
still sent, the responding Endpoint MUST expect that any such response
will be ignored.</p>
<p><em>Note: The requirement in the previous versions of the
specification also discouraged the sending of an <code>Error</code>
Message, however the Controller issuing the <code>Operate</code> might
want to learn about and handle errors occurring during the processing of
the <code>Operate</code> request but still ignore execution
results.</em></p>
<p><code>map&lt;string, string&gt; input_args</code></p>
<p>This field contains a map of key/value pairs indicating the input
arguments (relative to the Command Path in the command field) to be
passed to the method indicated in the command field.</p>
<p><strong><span id="r-opr.5"
class="auto-hoverlink">R-OPR.5</span></strong> - A <code>Command</code>
can have mandatory <code>input_args</code> as defined in the Supported
Data Model. When a mandatory Input argument is omitted from the
<code>input_args</code> field, the Agent MUST respond with an
<code>Error</code> of type <code>7004 Invalid arguments</code> and stop
processing the <code>Operate</code> Message.</p>
<p><strong><span id="r-opr.6"
class="auto-hoverlink">R-OPR.6</span></strong> - When an unrecognized
Input argument is included in the <code>input_args</code> field, the
Agent MUST ignore the Input argument and continue processing the
<code>Operate</code> Message.</p>
<p><strong><span id="r-opr.7"
class="auto-hoverlink">R-OPR.7</span></strong> - When a non-mandatory
Input argument is omitted from the <code>input_args</code> field, the
Agent MUST use a default value for the missing Input argument and
continue processing the <code>Operate</code> Message.</p>
<p>Refer to <a href="#sec:parameter-value-encoding"
class="heading">Parameter and Argument Value Encoding</a> for details of
how argument values are encoded as Protocol Buffers v3 strings.</p>
<h4 class="auto-hoverlink" data-info="header"
id="sec:operate-response-fields">7.7.7.2 Operate Response Fields</h4>
<p><code>repeated OperationResult operation_results</code></p>
<p>This field contains a repeated set of <code>OperationResult</code>
messages.</p>
<h5 class="auto-hoverlink" data-info="header"
id="sec:operationresult-fields">7.7.7.2.1 OperationResult Fields</h5>
<p><code>string executed_command</code></p>
<p>This field contains a Command Path to the Object defined Operation
that is the subject of this <code>OperateResp</code> message.</p>
<p><code>oneof operate_resp</code></p>
<p>This field contains a message of one of the following types.</p>
<pre><code>  string req_obj_path
  OutputArgs req_output_args
  CommandFailure cmd_failure</code></pre>
<h6 class="auto-hoverlink" data-info="header"
id="sec:using-req_obj_path">7.7.7.2.1.1 Using req_obj_path</h6>
<p>The req_obj_path field, when used as the <code>operate_resp</code>,
contains an Object Instance Path to the Request Object created as a
result of this asynchronous operation.</p>
<h6 class="auto-hoverlink" data-info="header"
id="sec:outputargs-fields-1">7.7.7.2.1.2 OutputArgs Fields</h6>
<p><code>map&lt;string, string&gt; output_args</code></p>
<p>This field contains a map of key/value pairs indicating the output
arguments (relative to the command specified in the <code>command</code>
field) returned by the method invoked in the Operate Message. Refer to
<a href="#sec:parameter-value-encoding" class="heading">Parameter and
Argument Value Encoding</a> for details of how argument values are
encoded as Protocol Buffers v3 strings.</p>
<h6 class="auto-hoverlink" data-info="header"
id="sec:commandfailure-fields-1">7.7.7.2.1.3 CommandFailure Fields</h6>
<p><code>fixed32 err_code</code></p>
<p>This field contains a numeric code (see <a href="#sec:error-codes"
class="heading">Error Codes</a>) indicating the type of the error that
caused the operation to fail.</p>
<p><code>string err_msg</code></p>
<p>This field contains additional (human readable) information about the
reason behind the error.</p>
<h4 class="auto-hoverlink" data-info="header"
id="sec:operate-message-error-codes">7.7.7.3 Operate Message Error
Codes</h4>
<p>Appropriate error codes for the Operate Message include
<code>7000-7008</code>, <code>7016</code>, <code>7022</code>,
<code>7026</code>, <code>7027</code>, and <code>7800-7999</code>.</p>
<h2 class="auto-hoverlink" data-info="header" id="sec:error-codes">7.8
Error Codes</h2>
<p>USP uses error codes with a range 7000-7999 for both Controller and
Agent errors. The errors appropriate for each Message (and how they must
be implemented) are defined in the message descriptions below.</p>
<table>
<colgroup>
<col style="width: 5%" />
<col style="width: 17%" />
<col style="width: 17%" />
<col style="width: 60%" />
</colgroup>
<thead>
<tr class="header">
<th style="text-align: left;">Code</th>
<th style="text-align: left;">Name</th>
<th style="text-align: left;">Applicability</th>
<th style="text-align: left;">Description</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;"><code>7000</code></td>
<td style="text-align: left;">Message failed</td>
<td style="text-align: left;">Error Message</td>
<td style="text-align: left;">This error indicates a general failure
that is described in an err_msg field.</td>
</tr>
<tr class="even">
<td style="text-align: left;"><code>7001</code></td>
<td style="text-align: left;">Message not supported</td>
<td style="text-align: left;">Error Message</td>
<td style="text-align: left;">This error indicates that the attempted
message was not understood by the target Endpoint.</td>
</tr>
<tr class="odd">
<td style="text-align: left;"><code>7002</code></td>
<td style="text-align: left;">Request denied (no reason specified)</td>
<td style="text-align: left;">Error Message</td>
<td style="text-align: left;">This error indicates that the target
Endpoint cannot or will not process the message.</td>
</tr>
<tr class="even">
<td style="text-align: left;"><code>7003</code></td>
<td style="text-align: left;">Internal error</td>
<td style="text-align: left;">Error Message</td>
<td style="text-align: left;">This error indicates that the message
failed due to internal hardware or software reasons.</td>
</tr>
<tr class="odd">
<td style="text-align: left;"><code>7004</code></td>
<td style="text-align: left;">Invalid arguments</td>
<td style="text-align: left;">Error Message</td>
<td style="text-align: left;">This error indicates that the message
failed due to invalid values in the USP message.</td>
</tr>
<tr class="even">
<td style="text-align: left;"><code>7005</code></td>
<td style="text-align: left;">Resources exceeded</td>
<td style="text-align: left;">Error Message</td>
<td style="text-align: left;">This error indicates that the message
failed due to memory or processing limitations on the target
Endpoint.</td>
</tr>
<tr class="odd">
<td style="text-align: left;"><code>7006</code></td>
<td style="text-align: left;">Permission denied</td>
<td style="text-align: left;">Error Message</td>
<td style="text-align: left;">This error indicates that the source
Endpoint does not have the authorization for this action.</td>
</tr>
<tr class="even">
<td style="text-align: left;"><code>7007</code></td>
<td style="text-align: left;">Invalid configuration</td>
<td style="text-align: left;">Error Message</td>
<td style="text-align: left;">This error indicates that the message
failed because processing the message would put the target Endpoint in
an invalid or unrecoverable state.</td>
</tr>
<tr class="odd">
<td style="text-align: left;"><code>7008</code></td>
<td style="text-align: left;">Invalid path syntax</td>
<td style="text-align: left;">any requested_path</td>
<td style="text-align: left;">This error indicates that the Path Name
used was not understood by the target Endpoint.</td>
</tr>
<tr class="even">
<td style="text-align: left;"><code>7009</code></td>
<td style="text-align: left;">Parameter action failed</td>
<td style="text-align: left;">Set</td>
<td style="text-align: left;">This error indicates that the Parameter
failed to update for a general reason described in an err_msg
field.</td>
</tr>
<tr class="odd">
<td style="text-align: left;"><code>7010</code></td>
<td style="text-align: left;">Unsupported parameter</td>
<td style="text-align: left;">Add, Set</td>
<td style="text-align: left;">This error indicates that the requested
Path Name associated with this ParamError or ParameterError did not
match any instantiated Parameters.</td>
</tr>
<tr class="even">
<td style="text-align: left;"><code>7011</code></td>
<td style="text-align: left;">Invalid type</td>
<td style="text-align: left;">Add, Set</td>
<td style="text-align: left;">This error indicates that the received
string can not be interpreted as a value of the correct type expected
for the Parameter.</td>
</tr>
<tr class="odd">
<td style="text-align: left;"><code>7012</code></td>
<td style="text-align: left;">Invalid value</td>
<td style="text-align: left;">Add, Set</td>
<td style="text-align: left;">This error indicates that the requested
value was not within the acceptable values for the Parameter.</td>
</tr>
<tr class="even">
<td style="text-align: left;"><code>7013</code></td>
<td style="text-align: left;">Attempt to update non-writeable
parameter</td>
<td style="text-align: left;">Add, Set</td>
<td style="text-align: left;">This error indicates that the source
Endpoint attempted to update a Parameter that is not defined as a
writeable Parameter.</td>
</tr>
<tr class="odd">
<td style="text-align: left;"><code>7014</code></td>
<td style="text-align: left;">Value conflict</td>
<td style="text-align: left;">Add, Set</td>
<td style="text-align: left;">This error indicates that the requested
value would result in an invalid configuration based on other Parameter
values.</td>
</tr>
<tr class="even">
<td style="text-align: left;"><code>7015</code></td>
<td style="text-align: left;">Operation error</td>
<td style="text-align: left;">Add, Set, Delete</td>
<td style="text-align: left;">This error indicates a general failure in
the creation, update, or deletion of an Object that is described in an
err_msg field.</td>
</tr>
<tr class="odd">
<td style="text-align: left;"><code>7016</code></td>
<td style="text-align: left;">Object does not exist</td>
<td style="text-align: left;">Any</td>
<td style="text-align: left;">This error indicates that the requested
Path Name did not address an Object in the Agent’s Instantiated Data
Model.</td>
</tr>
<tr class="even">
<td style="text-align: left;"><code>7017</code></td>
<td style="text-align: left;">Object could not be created</td>
<td style="text-align: left;">Add</td>
<td style="text-align: left;">This error indicates that the operation
failed to create an instance of the specified Object.</td>
</tr>
<tr class="odd">
<td style="text-align: left;"><code>7018</code></td>
<td style="text-align: left;">Object is not a table</td>
<td style="text-align: left;">Add, GetInstances</td>
<td style="text-align: left;">This error indicates that the requested
Path Name is not a Multi-Instance Object.</td>
</tr>
<tr class="even">
<td style="text-align: left;"><code>7019</code></td>
<td style="text-align: left;">Attempt to create non-creatable
object</td>
<td style="text-align: left;">Add</td>
<td style="text-align: left;">This error indicates that the source
Endpoint attempted to create an Object that is not defined as able to be
created.</td>
</tr>
<tr class="odd">
<td style="text-align: left;"><code>7020</code></td>
<td style="text-align: left;">Object could not be updated</td>
<td style="text-align: left;">Set</td>
<td style="text-align: left;">This error indicates that the requested
Object in a Set request failed to update.</td>
</tr>
<tr class="even">
<td style="text-align: left;"><code>7021</code></td>
<td style="text-align: left;">Required parameter failed</td>
<td style="text-align: left;">Add, Set</td>
<td style="text-align: left;">This error indicates that the request
failed on this Object because one or more required Parameters failed to
update. Details on the failed Parameters are included in an associated
ParamError or ParameterError message.</td>
</tr>
<tr class="odd">
<td style="text-align: left;"><code>7022</code></td>
<td style="text-align: left;">Command failure</td>
<td style="text-align: left;">Operate</td>
<td style="text-align: left;">This error indicates that an command
initiated in an Operate Request failed to complete for one or more
reasons explained in the err_msg field.</td>
</tr>
<tr class="even">
<td style="text-align: left;"><code>7023</code></td>
<td style="text-align: left;">Command canceled</td>
<td style="text-align: left;">Operate</td>
<td style="text-align: left;">This error indicates that an asynchronous
command initiated in an Operate Request failed to complete because it
was cancelled using the Cancel() operation.</td>
</tr>
<tr class="odd">
<td style="text-align: left;"><code>7024</code></td>
<td style="text-align: left;">Delete failure</td>
<td style="text-align: left;">Delete</td>
<td style="text-align: left;">This error indicates that this Object
Instance failed to be deleted.</td>
</tr>
<tr class="even">
<td style="text-align: left;"><code>7025</code></td>
<td style="text-align: left;">Object exists with duplicate key</td>
<td style="text-align: left;">Add, Set</td>
<td style="text-align: left;">This error indicates that an Object
already exists with the Unique Keys specified in an Add or Set
Message.</td>
</tr>
<tr class="odd">
<td style="text-align: left;"><code>7026</code></td>
<td style="text-align: left;">Invalid path</td>
<td style="text-align: left;">Any</td>
<td style="text-align: left;">This error indicates that the Object,
Parameter, or Command Path Name specified does not match any Objects,
Parameters, or Commands in the Agent’s Supported Data Model</td>
</tr>
<tr class="even">
<td style="text-align: left;"><code>7027</code></td>
<td style="text-align: left;">Invalid command arguments</td>
<td style="text-align: left;">Operate</td>
<td style="text-align: left;">This error indicates that an Operate
Message failed due to invalid or unknown arguments specified in the
command.</td>
</tr>
<tr class="odd">
<td style="text-align: left;"><code>7028</code></td>
<td style="text-align: left;">Register failure</td>
<td style="text-align: left;">Register</td>
<td style="text-align: left;">This error indicates that a path in a
Register Request failed to be registered for one or more reasons
explained in the err_msg field.</td>
</tr>
<tr class="even">
<td style="text-align: left;"><code>7029</code></td>
<td style="text-align: left;">Already in use</td>
<td style="text-align: left;">Register</td>
<td style="text-align: left;">This error indicates that a path in a
Register Request failed to be registered, because it was registered by a
different USP Agent</td>
</tr>
<tr class="odd">
<td style="text-align: left;"><code>7030</code></td>
<td style="text-align: left;">Deregister failure</td>
<td style="text-align: left;">Deregister</td>
<td style="text-align: left;">This error indicates that a path in a
Deregister Request failed to be deregistered for one or more reasons
explained in the err_msg field.</td>
</tr>
<tr class="even">
<td style="text-align: left;"><code>7031</code></td>
<td style="text-align: left;">Path already registered</td>
<td style="text-align: left;">Deregister</td>
<td style="text-align: left;">This error indicates that a path in a
Deregister Request failed to be deregistered, because it was registered
by a different USP Agent.</td>
</tr>
<tr class="odd">
<td style="text-align: left;"><code>7100-7199</code></td>
<td style="text-align: left;">USP Record error codes</td>
<td style="text-align: left;">-</td>
<td style="text-align: left;">These errors are listed and described in
<a href="#sec:usp-record-errors" class="heading">USP Record
Errors</a>.</td>
</tr>
<tr class="even">
<td style="text-align: left;"><code>7200-7299</code></td>
<td style="text-align: left;">Data model defined error codes</td>
<td style="text-align: left;">-</td>
<td style="text-align: left;">These errors are described in the data
model.</td>
</tr>
<tr class="odd">
<td style="text-align: left;"><code>7800-7999</code></td>
<td style="text-align: left;">Vendor defined error codes</td>
<td style="text-align: left;">-</td>
<td style="text-align: left;">These errors are described in <a
href="#sec:vendor-defined-error-codes" class="heading">Vendor Defined
Error Codes</a>.</td>
</tr>
</tbody>
</table>
<h3 class="auto-hoverlink" data-info="header"
id="sec:vendor-defined-error-codes">7.8.1 Vendor Defined Error
Codes</h3>
<p>Implementations of USP MAY specify their own error codes for use with
Errors and Responses. These codes use the <code>7800-7999</code> series.
There are no requirements on the content of these errors.</p>
<h1 class="auto-hoverlink" data-info="header" id="sec:auth">8
Authentication and Authorization</h1>
<p>USP contains mechanisms for Authentication and Authorization, and
Encryption. Encryption can be provided at the MTP layer, the USP layer,
or both. Where Endpoints can determine (through Authentication) that the
termination points of the MTP and USP messages are the same, MTP
encryption is sufficient to provide end-to-end encryption and security.
Where the termination points are different (because there is a proxy or
other intermediate device between the USP Endpoints), USP layer <a
href="#sec:e2e-message-exchange" class="heading">End to End Message
Exchange</a> is required, or the intermediate device must be a trusted
part of the end-to-end ecosystem.</p>
<h2 class="auto-hoverlink" data-info="header"
id="sec:authentication-1">8.1 Authentication</h2>
<p>Authentication of Controllers is done using X.509 certificates as
defined in <span class="citation" data-cites="RFC5280"><a
href="#ref-RFC5280" role="doc-biblioref">[34]</a></span> and <span
class="citation" data-cites="RFC6818"><a href="#ref-RFC6818"
role="doc-biblioref">[22]</a></span>. Authentication of Agents is done
either by using X.509 certificates or shared secrets. X.509
certificates, at a minimum, need to be usable for <a
href="#sec:securing-mtps" class="heading">Securing MTPs</a> with TLS or
DTLS protocols. It is recommended that Agents implement the ability to
encrypt all MTPs using one of these two protocols, enable it by default,
and not implement the ability to disable it.</p>
<p>In order to support various authentication models (e.g., trust
Endpoint identity and associated certificate on first use; precise
Endpoint identity is indicated in a certificate issued by a trusted
Certificate Authority; trust that MTP connection is being made to a
member of a trusted domain as verified by a trusted Certificate
Authority (CA)), this specification provides guidance based on
conditions under which the Endpoint is operating, and on the Endpoint’s
policy for storing certificates of other Endpoints or certificates of
trusted CAs. The <code>Device.LocalAgent.Certificate.</code> Object can
be implemented if choosing to expose these stored certificates through
the data model. See the <a href="#sec:theory-of-operations"
class="heading">Theory of Operations</a>, <a
href="#sec:certificate-management" class="heading">Certificate
Management</a> subsection, below for additional information.</p>
<p><strong><span id="r-sec.0"
class="auto-hoverlink">R-SEC.0</span></strong> - Prior to processing a
USP Message from a Controller, the Agent MUST either:</p>
<ul>
<li>have the Controller’s certificate information and have a
cryptographically protected connection between the two Endpoints,
or</li>
<li>have a Trusted Broker’s certificate information and have a
cryptographically protected connection between the Agent and the Trusted
Broker</li>
</ul>
<p><strong><span id="r-sec.0a"
class="auto-hoverlink">R-SEC.0a</span></strong> - Whenever a X.509
certificate is used to authenticate a USP Endpoint, the certificate MUST
contain a representation of the Endpoint ID in the
<code>subjectAltName</code> extension. This representation MUST be
either the URN form of the Endpoint ID with a type
<code>uniformResourceIdentifier</code> attribute OR, in the specific
case where the Endpoint ID has an <code>authority-scheme</code> of
<code>fqdn</code>, the <code>instance-id</code> portion of the Endpoint
ID with a type <code>dNSName</code> attribute. When this type of
authentication is used at the MTP layer, USP Endpoints MUST check the
<code>from_id</code> field of received USP Records and MUST NOT process
Records that do not match the Endpoint ID found in the certificate.</p>
<p>TLS and DTLS both have handshake mechanisms that allow for exchange
of certificate information. If the MTP connection is between the Agent
and Controller (for example, without going through any application-layer
proxy or other intermediate application-layer middle-box), then a secure
MTP connection will be sufficient to ensure end-to-end protection, and
the USP Record can use <code>payload_security</code> “PLAINTEXT”
encoding of the Message. If the middle-box is part of a trusted
end-to-end ecosystem, the MTP connection may also be considered
sufficient. Otherwise, the USP Record will use <a
href="#sec:e2e-message-exchange" class="heading">End to End Message
Exchange</a>.</p>
<p>Whether a Controller requires Agent certificates is left up to the
Controller implementation.</p>
<h2 class="auto-hoverlink" data-info="header" id="sec:rbac">8.2 Role
Based Access Control (RBAC)</h2>
<p>It is expected that Agents will have some sort of Access Control List
(ACL) that will define different levels of authorization for interacting
with the Agent’s data model. This specification refers to different
levels of authorization as “Roles”. The Agent may be so simple as to
only support a single Role that gives full access to its data model; or
it may have just an “untrusted” Role and a “full access” Role. Or it may
be significantly more complex with, for example, “untrusted” Role,
different Roles for parents and children in a customer household, and a
different Role for the service provider Controller. These Roles may be
fully defined in the Agent’s code, or Role definition may be allowed via
the data model.</p>
<p><strong><span id="r-sec.1"
class="auto-hoverlink">R-SEC.1</span></strong> - An Agent MUST confirm a
Controller has the necessary permissions to perform the requested
actions in a Message prior to performing that action.</p>
<p><strong><span id="r-sec.1a"
class="auto-hoverlink">R-SEC.1a</span></strong> - Agents SHOULD
implement the <code>Controller</code> Object with the
<code>AssignedRole</code> Parameter (with at least read-only data model
definition) and <code>InheritedRole</code> Parameter (if allowed Roles
can come from a trusted CA), so users can see what Controllers have
access to the Agent and their permissions. This will help users identify
rogue Controllers that may have gained access to the Agent.</p>
<p>See the <a href="#sec:theory-of-operations" class="heading">Theory of
Operations</a>, <a href="#sec:roles-access-control"
class="heading">Roles (Access Control)</a> and <a
href="#sec:assigning-controller-roles" class="heading">Assigning
Controller Roles</a> subsections, below for additional information on
data model elements that can be implemented to expose information and
allow control of Role definition and assignment.</p>
<h2 class="auto-hoverlink" data-info="header"
id="sec:trusted-certificate-authorities">8.3 Trusted Certificate
Authorities</h2>
<p>An Endpoint can have a configured list of trusted Certificate
Authority (CA) certificates. The Agent policy may trust the CA to
authorize authenticated Controllers to have a specific default Role, or
the policy may only trust the CA to authenticate the Controller
identity. The Controller policy may require an Agent certificate to be
signed by a trusted CA before the Controller exchanges USP Messages with
the Agent.</p>
<p><strong><span id="r-sec.2"
class="auto-hoverlink">R-SEC.2</span></strong> - To confirm a
certificate was signed by a trusted CA, the Endpoint MUST contain
information from one or more trusted CA certificates that are either
pre-loaded in the Endpoint or provided to the Endpoint by a secure
means. At a minimum, this stored information will include a certificate
fingerprint and fingerprint algorithm used to generate the fingerprint.
The stored information MAY be the entire certificate.</p>
<p>This secure means can be accomplished through USP (see <a
href="#sec:theory-of-operations" class="heading">Theory of
Operations</a>), <a href="#sec:certificate-management"
class="heading">Certificate Management</a> subsection, making use of the
<code>Device.LocalAgent.Certificate.</code> Object), or through a
mechanism external to USP. The stored CA certificates can be root or
intermediate CAs.</p>
<p><strong><span id="r-sec.3"
class="auto-hoverlink">R-SEC.3</span></strong> - Where a CA is trusted
to authenticate Controller identity, the Agent MUST ensure that the
Controller certificate conforms with the <a href="#r-sec.0a"
class="requirement">R-SEC.0a</a> requirement.</p>
<p><strong><span id="r-sec.4"
class="auto-hoverlink">R-SEC.4</span></strong> - Where a CA is trusted
to authorize a Controller Role, the Agent MUST ensure either that the
Controller certificate matches the certificate stored in the
<code>Credential</code> Parameter of the
<code>Device.LocalAgent.Controller.</code> entry specific to that
Controller OR that the Controller certificate itself is suitable for
authentication as per the <a href="#r-sec.0a"
class="requirement">R-SEC.0a</a> requirement.</p>
<p>Note that trusting a CA to authorize a Controller Role requires the
Agent to maintain an association between a CA certificate and the
Role(s) that CA is trusted to authorize. If the Agent allows CAs to
authorize Roles, the Agent will need to identify specific CA
certificates in a Controller’s chain of trust that can authorize Roles.
The specific Role(s) associated with such a CA certificate can then be
inherited by the Controller. The
<code>Device.LocalAgent.ControllerTrust.Credential.</code> Object can be
implemented to expose and allow control over trust and authorization of
CAs.</p>
<p>Note that if an Agent supports and has enabled a Trust on First Use
(TOFU) policy, it is possible for Controllers signed by unknown CAs to
be granted the “untrusted role”. See <a href="#fig:check-cert"
class="figure">Figure 22</a> and <a href="#fig:determine-role"
class="figure">Figure 23</a> and the penultimate bullet in the <a
href="#sec:assigning-controller-roles" class="heading">Assigning
Controller Roles</a> section below for more information related to TOFU
and the “untrusted” role.</p>
<h2 class="auto-hoverlink" data-info="header"
id="sec:trusted-brokers">8.4 Trusted Brokers</h2>
<p>An Endpoint can have a configured list of Trusted Broker
certificates. The Endpoint policy would be to trust the broker to vouch
for the identity of Endpoints it brokers – effectively authenticating
the <code>from_id</code> contained in a received USP Record. The Agent
policy may trust the broker to authorize all Controllers whose Records
transit the broker to have a specific default Role.</p>
<p><strong><span id="r-sec.4a"
class="auto-hoverlink">R-SEC.4a</span></strong> - To confirm a
certificate belongs to a Trusted Broker, the Endpoint MUST contain
information from one or more Trusted Broker certificates that are either
pre-loaded in the Endpoint or provided to the Endpoint by a secure
means. This stored information MUST be sufficient to determine if a
presented certificate is the Trusted Broker certificate.</p>
<p>This secure means of loading certificate information into an Agent
can be accomplished through USP (see <a href="#sec:theory-of-operations"
class="heading">Theory of Operations</a> section related to <a
href="#sec:certificate-management" class="heading">Certificate
Management</a>), or through a mechanism external to USP.</p>
<p>Note that trusting a broker to authorize a Controller Role requires
the Agent to maintain an association between a Trusted Broker
certificate and the Role(s) that Trusted Broker is trusted to authorize.
The <code>Device.LocalAgent.ControllerTrust.Credential.</code> Object
can be implemented to expose and allow control over identifying Trusted
Brokers. The <code>AllowedUses</code> Parameter is used to indicate
whether an entry is a Trusted Broker.</p>
<p><strong><span id="r-sec.4b"
class="auto-hoverlink">R-SEC.4b</span></strong> - A Trusted Broker MUST
confirm the identity of all clients by exclusively allowing
authentication via unique client certificates that identify the USP
Endpoint. Also the confidentiality of all communications MUST be
guaranteed by a Trusted Broker, i.e. there MUST NOT be any possibility
to forward the communication between Endpoints to another party.</p>
<p><strong><span id="r-sec.4c"
class="auto-hoverlink">R-SEC.4c</span></strong> - A Trusted Broker MUST
guarantee that USP Records sent from clients contain the correct value
for the <code>from_id</code> field, tying it to the identity provided
during the connection establishment. A Trusted Broker MUST NOT inspect
USP payloads contained in USP Records.</p>
<h2 class="auto-hoverlink" data-info="header"
id="sec:self-signed-certificates">8.5 Self-Signed Certificates</h2>
<p><strong><span id="r-sec.5"
class="auto-hoverlink">R-SEC.5</span></strong> - An Endpoint that
generates a self-signed certificate MUST ensure that the certificate is
suitable for USP authentication as per the <a href="#r-sec.0a"
class="requirement">R-SEC.0a</a> requirement.</p>
<p>Self-signed certificates supplied by Controllers can only be
meaningfully used in cases where a person is in a position to provide
Authorization (what Role the Controller is trusted to have). Whether or
not an Agent allows self-signed certificates from a Controller is a
matter of Agent policy.</p>
<p><strong><span id="r-sec.6"
class="auto-hoverlink">R-SEC.6</span></strong> - If an Agent allows
Controllers to provide self-signed certificates, the Agent MUST assign
such Controllers an “untrusted” Role on first use.</p>
<p>That is, the Agent will trust the certificate for purpose of
encryption, but will heavily restrict what the Controller is authorized
to do. See <a href="#fig:check-cert" class="figure">Figure 22</a> and <a
href="#fig:determine-role" class="figure">Figure 23</a> and the
penultimate bullet in the <a href="#sec:assigning-controller-roles"
class="heading">Assigning Controller Roles</a> section below for more
information related to TOFU and the “untrusted” role.</p>
<p><strong><span id="r-sec.7"
class="auto-hoverlink">R-SEC.7</span></strong> - If an Agent allows
Controllers to provide self-signed certificates, the Agent MUST have a
means of allowing an external entity to change the Role of each such
Controller.</p>
<p>Controller policy related to trust of Agent self-signed certificates
is left to the Controller. Controllers may be designed to refuse
self-signed certificates (thereby refusing to control the Agent), they
may have a means of allowing a person to approve controlling the Agent
via the Controller, or they may automatically accept the Agent.</p>
<p><strong><span id="r-sec.8"
class="auto-hoverlink">R-SEC.8</span></strong> - An Endpoint that
accepts self-signed certificates MUST maintain the association of
accepted certificate and Endpoint IDs.</p>
<p>Self-signed certificates require a “trust on first use” (TOFU) policy
when using them to authenticate an Endpoint’s identity. An external
entity (a trusted Controller or user) can then authorize the
authenticated Endpoint to have certain permissions. Subsequent to the
first use, this same self-signed certificate can be trusted to establish
the identity of that Endpoint. However, authentication of the Endpoint
can only be subsequently trusted if the association of certificate to
identity is remembered (i.e., it is known this is the same certificate
that was used previously by that Endpoint). If it is not remembered,
then every use is effectively a first use and would need to rely on an
external entity to authorize permissions every time. The
<code>Device.LocalAgent.Certificate.</code> Object can be implemented if
choosing to expose and allow control of remembered certificates in the
data model.</p>
<h2 class="auto-hoverlink" data-info="header"
id="sec:agent-authentication">8.6 Agent Authentication</h2>
<p><strong><span id="r-sec.9"
class="auto-hoverlink">R-SEC.9</span></strong> - Controllers MUST
authenticate Agents either through X.509 certificates, a shared secret,
or by trusting a Trusted Broker to vouch for Agent identity.</p>
<p>When authentication is done using X.509 certificates, it is up to
Controller policy whether to allow for Agents with self-signed
certificates or to require Agent certificates be signed by a CA.</p>
<p>Note that allowing use of, method for transmitting, and procedure for
handling shared secrets is specific to the MTP used, as described in <a
href="#sec:mtp" class="heading">Message Transfer Protocols</a>. Shared
secrets that are not unique per device are not recommended as they leave
devices highly vulnerable to various attacks – especially devices
exposed to the Internet.</p>
<p><strong><span id="r-sec.10"
class="auto-hoverlink">R-SEC.10</span></strong> - An Agent certificate
MUST be suitable for USP authentication as per the <a href="#r-sec.0a"
class="requirement">R-SEC.0a</a> requirement.</p>
<p><strong><span id="r-sec.10a"
class="auto-hoverlink">R-SEC.10a</span></strong> - The certificate
<code>subjectAltName</code> extension MUST be used to authenticate the
USP Record <code>from_id</code> for any Records secured with an Agent
certificate.</p>
<p>Agent certificates can be used to secure Records by encrypting at the
<a href="#sec:mtp" class="heading">MTP layer</a> and/or encrypting at
the <a href="#sec:e2e-message-exchange" class="heading">USP
layer</a>.</p>
<p>Some Controller implementations may allow multiple Agents to share a
single certificate with a wildcarded Endpoint ID.</p>
<p><strong><span id="r-sec.11"
class="auto-hoverlink">R-SEC.11</span></strong> - If a single
certificate is shared among multiple Agents, those Agents MUST include a
wild-carded <code>instance-id</code> in the Endpoint ID in the
<code>subjectAltName</code> extension with identical
<code>authority-scheme</code> and <code>authority-id</code>.</p>
<p>Use of a shared certificate is not recommended, and which portion of
the <code>instance-id</code> can be wildcarded may be specific to the
authorizing CA or to the <code>authority-id</code> and
<code>authority-scheme</code> values of the Endpoint ID. Wildcards can
only be allowed in cases where the assigning entity is explicitly
identified. Controllers are not required to support wildcarded
certificates.</p>
<p><strong><span id="r-sec.12"
class="auto-hoverlink">R-SEC.12</span></strong> - If a wildcard
character is present in the <code>instance-id</code> of an Endpoint ID
in a certificate <code>subjectAltName</code> extension, the
<code>authority-scheme</code> MUST be one of “oui”, “cid”, “pen”, “os”,
or “ops”. In the case of “os” and “ops”, the portion of the
<code>instance-id</code> that identifies the assigning entity MUST NOT
be wildcarded.</p>
<h2 class="auto-hoverlink" data-info="header"
id="sec:challenge-strings-and-images">8.7 Challenge Strings and
Images</h2>
<p>It is possible for the Agent to allow an external entity to change a
Controller Role by means of a Challenge string or image. This Challenge
string or image can take various forms, including having a user supply a
passphrase or a PIN. Such a string could be printed on the Agent
packaging, or supplied by means of a SMS to a phone number associated
with the user account. These Challenge strings or images can be done
using USP operations. Independent of how challenges are accomplished,
following are some basic requirements related to Challenge strings and
images.</p>
<p><strong><span id="r-sec.13"
class="auto-hoverlink">R-SEC.13</span></strong> - The Agent MAY have
factory-default Challenge value(s) (strings or images) in its
configuration.</p>
<p><strong><span id="r-sec.14"
class="auto-hoverlink">R-SEC.14</span></strong> - A factory-default
Challenge value MUST be unique to the Agent. Re-using the same
passphrase among multiple Agents is not permitted.</p>
<p><strong><span id="r-sec.15"
class="auto-hoverlink">R-SEC.15</span></strong> - A factory-default
Challenge value MUST NOT be derivable from information the Agent
communicates about itself using any protocol at any layer.</p>
<p><strong><span id="r-sec.16"
class="auto-hoverlink">R-SEC.16</span></strong> - The Agent MUST limit
the number of tries for the Challenge value to be supplied
successfully.</p>
<p><strong><span id="r-sec.17"
class="auto-hoverlink">R-SEC.17</span></strong> - The Agent SHOULD have
policy to lock out all use of Challenge values for some time, or
indefinitely, if the number of tries limit is exceeded.</p>
<p>See the <a href="#sec:theory-of-operations" class="heading">Theory of
Operations</a>, <a href="#sec:challenges" class="heading">Challenges</a>
subsection, below for a description of data model elements that need to
be implemented and are used when doing challenges through USP
operations.</p>
<h2 class="auto-hoverlink" data-info="header"
id="sec:analysis-controller-certificates">8.8 Analysis of Controller
Certificates</h2>
<p>An Agent will analyze Controller certificates to determine if they
are valid, are appropriate for authentication of Controllers, and to
determine what permissions (Role) a Controller has. The Agent will also
determine whether MTP encryption is sufficient to provide end-to-end
protection of the Record and Message, or if USP layer <a
href="#sec:e2e-message-exchange" class="heading">End to End Message
Exchange</a> is required.</p>
<p>The diagrams in this section use the database symbol to identify
where the described information can be represented in the data model, if
an implementation chooses to expose this information through the USP
protocol.</p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:receiving-a-usp-record">8.8.1 Receiving a USP Record</h3>
<p><strong><span id="r-sec.19"
class="auto-hoverlink">R-SEC.19</span></strong> - An Agent capable of
obtaining absolute time SHOULD wait until it has accurate absolute time
before contacting a Controller. If an Agent for any reason is unable to
obtain absolute time, it can contact the Controller without waiting for
accurate absolute time. If an Agent chooses to contact a Controller
before it has accurate absolute time (or if it does not support absolute
time), it MUST ignore those components of the Controller certificate
that involve absolute time, e.g. not-valid-before and not-valid-after
certificate restrictions.</p>
<p><strong><span id="r-sec.20"
class="auto-hoverlink">R-SEC.20</span></strong> - An Agent that has
obtained accurate absolute time MUST validate those components of the
Controller certificate that involve absolute time.</p>
<p><strong><span id="r-sec.21"
class="auto-hoverlink">R-SEC.21</span></strong> – An Agent MUST clear
all cached encryption session and Role authorization information when it
reboots.</p>
<p><strong><span id="r-sec.22"
class="auto-hoverlink">R-SEC.22</span></strong> - When an Agent receives
a USP Record, the Agent MUST execute logic that achieves the same
results as in the mandatory decision flow elements (identified with
“MUST”) from <a href="#fig:receive-record" class="figure">Figure 19</a>
and <a href="#fig:no-secure-message-exchange" class="figure">Figure
20</a>.</p>
<p><strong><span id="r-sec.22a"
class="auto-hoverlink">R-SEC.22a</span></strong> - When an Agent
receives a USP Record, the Agent SHOULD execute logic that achieves the
same results as in the optional decision flow elements (identified with
“OPT”) from <a href="#fig:receive-record" class="figure">Figure 19</a>
and <a href="#fig:no-secure-message-exchange" class="figure">Figure
20</a>.</p>
<figure id="fig:receive-record">
<img src="security/receive-record.png" id="img:receiving-a-usp-record"
alt="Receiving a USP Record" />
<figcaption><div class="auto-hoverlink"
data-anchor="fig:receive-record">
Figure 19: Receiving a USP Record
</div></figcaption>
</figure>
<hr />
<figure id="fig:no-secure-message-exchange">
<img src="security/no-secure-message-exchange.png"
id="img:usp-record-without-usp-layer-secure-message-exchange"
alt="USP Record without USP Layer Secure Message Exchange" />
<figcaption><div class="auto-hoverlink"
data-anchor="fig:no-secure-message-exchange">
Figure 20: USP Record without USP Layer Secure Message Exchange
</div></figcaption>
</figure>
<h3 class="auto-hoverlink" data-info="header"
id="sec:sending-a-usp-record">8.8.2 Sending a USP Record</h3>
<p><strong><span id="r-sec.23"
class="auto-hoverlink">R-SEC.23</span></strong> - When an Agent sends a
USP Record, the Agent MUST execute logic that achieves the same results
as in the mandatory decision flow elements (identified with “MUST”) from
<a href="#fig:send-record" class="figure">Figure 21</a>.</p>
<p><strong><span id="r-sec.23a"
class="auto-hoverlink">R-SEC.23a</span></strong> - When an Agent sends a
USP Record, the Agent SHOULD execute logic that achieves the same
results as in the optional decision flow elements (identified with
“OPT”) from <a href="#fig:send-record" class="figure">Figure 21</a>.</p>
<figure id="fig:send-record">
<img src="security/send-record.png" id="img:sending-a-usp-record"
alt="Sending a USP Record" />
<figcaption><div class="auto-hoverlink" data-anchor="fig:send-record">
Figure 21: Sending a USP Record
</div></figcaption>
</figure>
<h3 class="auto-hoverlink" data-info="header"
id="sec:checking-a-certificate">8.8.3 Checking a Certificate</h3>
<p><strong><span id="r-sec.24"
class="auto-hoverlink">R-SEC.24</span></strong> - When an Agent analyzes
a Controller certificate for authentication and determining permissions
(Role), the Agent MUST execute logic that achieves the same results as
in the mandatory decision flow elements (identified with “MUST”) from <a
href="#fig:check-cert" class="figure">Figure 22</a> and <a
href="#fig:determine-role" class="figure">Figure 23</a>.</p>
<p><strong><span id="r-sec.24a"
class="auto-hoverlink">R-SEC.24a</span></strong> - When an Agent
analyzes a Controller certificate for authentication and determining
permissions (Role), the Agent SHOULD execute logic that achieves the
same results as in the optional decision flow elements (identified with
“OPT”) from <a href="#fig:check-cert" class="figure">Figure 22</a> and
<a href="#fig:determine-role" class="figure">Figure 23</a>.</p>
<p><strong><span id="r-sec.25"
class="auto-hoverlink">R-SEC.25</span></strong> - When determining the
inherited Role to apply based on Roles associated with a trusted CA,
only the first matching CA in the chain will be used.</p>
<figure id="fig:check-cert">
<img src="security/check-cert.png" id="img:checking-a-certificate"
alt="Checking a Certificate" />
<figcaption><div class="auto-hoverlink" data-anchor="fig:check-cert">
Figure 22: Checking a Certificate
</div></figcaption>
</figure>
<hr />
<figure id="fig:determine-role">
<img src="security/determine-role.png" id="img:determining-the-role"
alt="Determining the Role" />
<figcaption><div class="auto-hoverlink"
data-anchor="fig:determine-role">
Figure 23: Determining the Role
</div></figcaption>
</figure>
<h3 class="auto-hoverlink" data-info="header"
id="sec:using-a-trusted-broker">8.8.4 Using a Trusted Broker</h3>
<p>Support for Trusted Broker logic is optional.</p>
<p><strong><span id="r-sec.26"
class="auto-hoverlink">R-SEC.26</span></strong> - If Trusted Brokers are
supported, and a Trusted Broker is encountered (from the optional “OPT”
“Trusted Broker cert?” decision diamonds in <a
href="#fig:no-secure-message-exchange" class="figure">Figure 20, Figure
21</a>) the Agent MUST execute logic that achieves the same results as
in the mandatory decision flow elements (identified with “MUST”) from <a
href="#fig:broker-with-received-record" class="figure">Figure 24</a> for
a received USP Record and <a href="#fig:broker-with-sent-record"
class="figure">Figure 25</a> for sending a USP Record.</p>
<p><strong><span id="r-sec.26a"
class="auto-hoverlink">R-SEC.26a</span></strong> - If Trusted Brokers
are supported, and a Trusted Broker is encountered (from the optional
“OPT” “Trusted Broker cert?” decision diamonds in <a
href="#fig:no-secure-message-exchange" class="figure">Figure 20, Figure
21</a>) the Agent SHOULD execute logic that achieves the same results as
in the optional decision flow elements (identified with “OPT”) from <a
href="#fig:broker-with-received-record" class="figure">Figure 24</a> for
a received USP Record and <a href="#fig:broker-with-sent-record"
class="figure">Figure 25</a> for sending a USP Record.</p>
<figure id="fig:broker-with-received-record">
<img src="security/broker-with-received-record.png"
id="img:trusted-broker-with-received-record"
alt="Trusted Broker with Received Record" />
<figcaption><div class="auto-hoverlink"
data-anchor="fig:broker-with-received-record">
Figure 24: Trusted Broker with Received Record
</div></figcaption>
</figure>
<hr />
<figure id="fig:broker-with-sent-record">
<img src="security/broker-with-sent-record.png"
id="img:trusted-broker-sending-a-record"
alt="Trusted Broker Sending a Record" />
<figcaption><div class="auto-hoverlink"
data-anchor="fig:broker-with-sent-record">
Figure 25: Trusted Broker Sending a Record
</div></figcaption>
</figure>
<h2 class="auto-hoverlink" data-info="header"
id="sec:theory-of-operations">8.9 Theory of Operations</h2>
<p>The following theory of operations relies on Objects, Parameters,
events, and operations from the <code>LocalAgent</code> Object of the
Device:2 Data Model <span class="citation" data-cites="TR-181"><a
href="#ref-TR-181" role="doc-biblioref">[3]</a></span>.</p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:data-model-elements">8.9.1 Data Model Elements</h3>
<p>These data model elements play a role in reporting on and allowing
control of trusted Controllers and the permissions they have to read and
write parts of the Agent’s data model, and allowing an Agent to
establish trust with a Controller.</p>
<ul>
<li><code>LocalAgent.Controller.{i}.AssignedRole</code> Parameter</li>
<li><code>LocalAgent.Controller.{i}.InheritedRole</code> Parameter</li>
<li><code>LocalAgent.Controller.{i}.Credential</code> Parameter</li>
</ul>
<p>From component <code>ControllerTrust</code>:</p>
<ul>
<li>Object <code>LocalAgent.ControllerTrust.</code></li>
<li>Parameters <code>UntrustedRole</code>, <code>BannedRole</code>,
<code>SecuredRoles</code>, <code>TOFUAllowed</code>,
<code>TOFUInactivityTimer</code></li>
<li>Commands <code>RequestChallenge()</code>,
<code>ChallengeResponse()</code></li>
<li>Object <code>LocalAgent.ControllerTrust.Role.{i}.</code></li>
<li>Object <code>LocalAgent.ControllerTrust.Credential.{i}.</code></li>
<li>Object <code>LocalAgent.ControllerTrust.Challenge.{i}.</code></li>
</ul>
<p>The Object <code>LocalAgent.Certificate.</code> can be used to manage
Controller and CA certificates, along with the
<code>LocalAgent.AddCertificate()</code> and
<code>LocalAgent.Controller.{i}.AddMyCertificate()</code> commands.</p>
<p>For brevity, <code>Device.LocalAgent.</code> is not placed in front
of all further Object references in this Security section. However, all
Objects references are under <code>Device.LocalAgent.</code>. This
section does not describe use of Parameters under other top level
components.</p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:roles-access-control">8.9.2 Roles (Access Control)</h3>
<p>Controller permissions are conveyed in the data model through
Roles.</p>
<h4 class="auto-hoverlink" data-info="header"
id="sec:role-definition">8.9.2.1 Role Definition</h4>
<p>A Role is described in the data model through use of the
<code>ControllerTrust.Role.{i}.</code> Object. Each entry in this Object
identifies the Role it describes, and has a <code>Permission.</code>
Sub-Object for the <code>Targets</code> (data model Path Names that the
related permissions apply to), permissions related to Parameters,
Objects, instantiated Objects, and commands identified by the
<code>Targets</code> Parameter, and the relative <code>Order</code> of
precedence among <code>Permission.</code> entries for the Role (the
larger value of this Parameter takes priority over an entry with a
smaller value in the case of overlapping <code>Targets</code> entries
for the Role).</p>
<p>The permissions of a Role for the specified <code>Target</code>
entries are described by <code>Param</code>, <code>Obj</code>,
<code>InstantiatedObj</code>, and <code>CommandEvent</code> Parameters.
Each of these is expressed as a string of 4 characters where each
character represents a permission (“<code>r</code>” for Read,
“<code>w</code>” for Write, “<code>x</code>” for Execute”, and
“<code>n</code>” for Notify). The 4 characters are always presented in
the same order in the string (<code>rwxn</code>) and the lack of a
permission is signified by a “<code>-</code>” character (e.g.,
<code>r--n</code>). How these permissions are applied to Parameters,
Objects, and various Messages is described in the data model description
of these Parameters.</p>
<p>An Agent that wants to allow Controllers to define and modify Roles
will implement the <code>ControllerTrust.Role.{i}.</code> Object with
all of the Parameters listed in the data model. In order for a
Controller to define or modify Role entries, it will need to be assigned
a Role that gives it the necessary permission. Care should be taken to
avoid defining this Role’s permissions such that an Agent with this Role
can modify the Role and no longer make future modifications to the
<code>ControllerTrust.Role.{i}.</code> Object.</p>
<p>A simple Agent that only wants to inform Controllers of pre-defined
Roles (with no ability to modify or define additional Roles) can
implement the <code>ControllerTrust.Role.</code> Object with read-only
data model definition for all entries and Parameters. A simple Agent
could even implement the Object with read-only data model definition and
just the <code>Alias</code> and <code>Role</code> Parameters, and no
<code>Permission.</code> Sub-Object; this could be sufficient in a case
where the Role names convey enough information (e.g., there are only two
pre-defined Roles named <code>"Untrusted"</code> and
<code>"FullAccess"</code>).</p>
<h4 class="auto-hoverlink" data-info="header"
id="sec:special-roles">8.9.2.2 Special Roles</h4>
<p>Three special Roles are identified by the <code>UntrustedRole</code>,
<code>BannedRole</code> and <code>SecuredRoles</code> Parameters under
the <code>ControllerTrust.</code> Object. An Agent can expose these
Parameters with read-only data model implementation if it simply wants
to tell Controllers the names of these specific Roles.</p>
<p>The <code>UntrustedRole</code> is the Role the Agent will
automatically assign to any Controller that has not been authorized for
a different Role. Any Agent that has a means of allowing a Controller’s
Role to be changed (by users through a Challenge string, by other
Controllers through modification of
<code>Controller.{i}.AssignedRole</code>, or through some other external
means) and that allows “unknown” Controllers to attach will need to have
an “untrusted” Role defined; even if the identity of this Role is not
exposed to Controllers through implementation of the
<code>UntrustedRole</code> Parameter.</p>
<p>The <code>BannedRole</code> (if implemented) is assigned
automatically by the Agent to Controllers whose certificates have been
revoked. If it is not implemented, the Agent can use the
<code>UntrustedRole</code> for this, as well. It is also possible to
simply implement policy for treatment of invalid or revoked certificates
(e.g., refuse to connect), rather than associate them with a specific
Role. This is left to the Agent policy implementation.</p>
<p>The <code>SecuredRoles</code> (if implemented) is the Role assigned
to Controllers that are authorized to have access to
<code>secured</code> Parameter values. If the <code>SecuredRoles</code>
is not assigned to a given Controller, or if the
<code>SecuredRoles</code> is not implemented, then <code>secured</code>
Parameters are to be considered as <code>hidden</code>, in which case
the Agent returns a null value, e.g. an empty string, to this
Controller, regardless of the actual value. Only Controllers with a
secured Role assigned (and the appropriate permissions set), are able to
have access to secured parameter values.</p>
<h4 class="auto-hoverlink" data-info="header"
id="sec:a-controllers-role">8.9.2.3 A Controller’s Role</h4>
<p>A Controller’s assigned Roles can be conveyed by the
<code>Controller.{i}.AssignedRole</code> Parameter. This Parameter is a
list of all Role values assigned to the Controller through means other
than <code>ControllerTrust.Credential.{i}.Role</code>. A Controller’s
inherited Roles (those inherited from
<code>ControllerTrust.Credential.{i}.Role</code> as described in the
next section) need to be maintained separately from assigned Roles and
can be conveyed by the <code>Controller.{i}.InheritedRole</code>
Parameter. Where multiple assigned and inherited Roles have overlapping
<code>Targets</code> entries, the resulting permission is the union of
all assigned and inherited permissions. For example, if two Roles have
the same <code>Targets</code> with one Role assigning the
<code>Targets</code> <code>Param</code> a value of <code>r---</code> and
the other Role assigning <code>Param</code> a value of
<code>---n</code>, the resulting permission will be <code>r--n</code>.
This is done after determining which
<code>ControllerTrust.Role.{i}.Permission.{i}</code> entry to apply for
each Role for specific <code>Targets</code>, in the case where a Role
has overlapping <code>Permission.{i}.Targets</code> entries for the same
Role.</p>
<p>For example, Given the following
<code>ControllerTrust.Role.{i}.</code> entries:</p>
<pre><code>  i=1, Role = &quot;A&quot;; Permission.1.: Targets = &quot;Device.LocalAgent.&quot;, Order = 3, Param = &quot;r---&quot;
  i=1, Role = &quot;A&quot;; Permission.2.: Targets = &quot;Device.LocalAgent.Controller.&quot;, Order = 55, Param = &quot;r-xn&quot;
  i=3, Role = &quot;B&quot;; Permission.1: Targets = &quot;Device.LocalAgent.&quot;, Order = 20, Param = &quot;r---&quot;
  i=3, Role = &quot;B&quot;; Permission.5: Targets = &quot;Device.LocalAgent.Controller.&quot;, Order = 78, Param = &quot;----&quot;</code></pre>
<p>and <code>Device.LocalAgent.Controller.1.AssignedRole</code> =
“Device.LocalAgent. ControllerTrust.Role.1., Device.LocalAgent.
ControllerTrust.Role.3.”</p>
<p>When determining permissions for the
<code>Device.LocalAgent.Controller.</code> table, the Agent will first
determine that for Role A Permission.2 takes precedence over
Permission.1 (55 &gt; 3). For B, Permission.5 takes precedence over
Permission.1 (78 &gt; 20). The union of A and B is “r-xn” + “—-” =
“r-xn”.</p>
<h4 class="auto-hoverlink" data-info="header"
id="sec:role-associated-with-a-credential-or-challenge">8.9.2.4 Role
Associated with a Credential or Challenge</h4>
<p>The <code>ControllerTrust.Credential.{i}.Role</code> Parameter value
is inherited by Controllers whose credentials have been validated using
the credentials in the same entry of the
<code>ControllerTrust.Credential.{i}.</code> table. Whenever
<code>ControllerTrust.Credential.{i}.</code> is used to validate a
certificate, the Agent writes the current value of the associated
<code>ControllerTrust.Credential.{i}.Role</code> into the
<code>Controller.{i}.InheritedRole</code> Parameter. For more
information on use of this table for assigning Controller Roles and
validating credentials, see the sections below.</p>
<p>The <code>ControllerTrust.Challenge.{i}.Role</code> Parameter is a
Role that is assigned to Controllers that send a successful
<code>ChallengeResponse()</code> command. For more information on use of
challenges for assigning Controller Roles, see the sections below.</p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:assigning-controller-roles">8.9.3 Assigning Controller
Roles</h3>
<p>As mentioned above, the <code>Controller.{i}.AssignedRole</code>
Parameter can be used to expose the Controller’s assigned Role via the
data model.</p>
<p><em>Note: Even if it is not exposed through the data model, the Agent
is expected to maintain knowledge of the permissions assigned to each
known Controller.</em></p>
<p>Controllers can be assigned Roles through a variety of methods,
depending on the data model elements an Agent implements and the Agent’s
coded policy. Note that it is possible for an Agent to maintain trusted
CA credentials with associated permissions (as described by the
<code>ControllerTrust.Credential.{i}.</code> Object) and various default
permission definitions (as identified by the <code>UntrustedRole</code>
and <code>BannedRole</code> Parameters) without exposing these through
the data model. If the data is maintained but not exposed, the same
methods can still be used.</p>
<p><a href="#fig:check-cert" class="figure">Figure 22</a> and <a
href="#fig:determine-role" class="figure">Figure 23</a> in the above <a
href="#sec:analysis-controller-certificates" class="heading">Analysis of
Controller Certificates</a> section identify points in the decision
logic where some of the following calls to data model Parameters can be
made. The following bullets note when they are identified in one of
these figures.</p>
<ul>
<li><p>Another Controller (with appropriate permission) can insert a
Controller (including the <code>AssignedRole</code> Parameter value)
into the <code>Controller.{i}.</code> table, or can modify the
<code>AssignedRole</code> Parameter of an existing
<code>Controller.{i}.</code> entry. The <code>InheritedRole</code> value
cannot be modified by another Controller.</p></li>
<li><p>If credentials in an entry in a
<code>ControllerTrust.Credential.{i}.Credential</code> Parameter with an
associated <code>ControllerTrust.Credential.{i}.Role</code> Parameter
are used to successfully validate the certificate presented by the
Controller, the Controller inherits the Role from the associated
<code>ControllerTrust.Credential.{i}.Role</code>. The Agent writes this
value to the <code>Controller.{i}.InheritedRole</code> Parameter. This
step is shown in <a href="#fig:determine-role" class="figure">Figure
23</a>.</p></li>
<li><p>A Controller whose associated certificate is revoked by a CA can
be assigned the role in <code>BannedRole</code>, if this Parameter or
policy is implemented. In this case, the value of
<code>BannedRole</code> must be the only value in
<code>Controller.{i}.AssignedRole</code> (all other entries are removed)
and <code>Controller.{i}.InheritedRole</code> must be empty (all entries
are removed). This step is shown in <a href="#fig:check-cert"
class="figure">Figure 22</a>. In the case of a Controller that has not
previously been assigned a Role or who has been assigned the value of
<code>UntrustedRole</code>:</p></li>
<li><p>If the Controller’s certificate is validated by credentials in a
<code>ControllerTrust.Credential.{i}.Credential</code> Parameter but
there is no associated <code>ControllerTrust.Credential.{i}.Role</code>
Parameter (or the value is empty) and
<code>Controller.{i}.AssignedRole</code> is empty, then the Controller
is assigned the role in <code>UntrustedRole</code> (written to the
<code>Controller.{i}.AssignedRole</code> Parameter). This step is shown
in <a href="#fig:determine-role" class="figure">Figure 23</a>. Note that
assigning <code>UntrustedRole</code> means there needs to be some
implemented way to elevate the Controller’s Role, either by another
Controller manipulating the Role, implementing Challenges, or some
non-USP method.</p></li>
<li><p>If the Controller’s certificate is self-signed or is validated by
credentials not in <code>ControllerTrust.Credential.{i}.</code>, the
Agent policy may be to assign the role in <code>UntrustedRole</code>.
The optional policy decision (whether or not to allow Trust on First Use
(TOFU), which can be codified in the data model with the
ControllerTrust.TOFUAllowed flag) is shown in <a href="#fig:check-cert"
class="figure">Figure 22</a>; <a href="#fig:determine-role"
class="figure">Figure 23</a> shows the Role assignment.</p></li>
<li><p>If the Agent implements the <code>RequestChallenge()</code> and
<code>ChallengeResponse()</code> commands, a Controller assigned the
role in <code>UntrustedRole</code> can have permission to read one or
more <code>ControllerTrust.Challenge.{i}.Alias</code> and
<code>Description</code> values and issue the commands. Roles with more
extensive permissions can have permission to read additional
<code>ControllerTrust.Challenge.{i}.Alias</code> and
<code>Description</code> values. A successful Challenge results in the
Controller being assigned the associated Role value.</p></li>
</ul>
<h3 class="auto-hoverlink" data-info="header"
id="sec:controller-certificates-and-certificate-validation">8.9.4
Controller Certificates and Certificate Validation</h3>
<p>When an Agent is presented with a Controller’s certificate, the Agent
will always attempt to validate the certificate to whatever extent
possible. <a href="#fig:no-secure-message-exchange"
class="figure">Figure 20, Figure 22</a> and <a
href="#fig:determine-role" class="figure">Figure 23</a> identify points
in the decision logic where data model Parameters can be used to
influence policy decisions related to Controller certificate
analysis.</p>
<p>Note that it is possible for an Agent to maintain policy of the type
described by the <code>UntrustedRole</code>, <code>BannedRole</code>,
and the information described by
<code>ControllerTrust.Credential.{i}.</code> and
<code>Controller.{i}.Credential</code> without exposing these through
the data model. If the policy concepts and data are maintained but not
exposed, the same methods can still be used. It is also possible for an
Agent to have policy that is not described by any defined data model
element.</p>
<h3 class="auto-hoverlink" data-info="header" id="sec:challenges">8.9.5
Challenges</h3>
<p>An Agent can implement the ability to provide Controllers with
challenges via USP, in order to be trusted with certain Roles. It is
also possible to use non-USP methods to issue challenges, such as HTTP
digest authentication with prompts for login and password.</p>
<p>To use the USP mechanism, the <code>RequestChallenge()</code> and
<code>ChallengeResponse()</code> commands and
<code>ControllerTrust.Challenge.{i}.</code> Object with at least the
<code>Alias</code>, <code>Role</code>, and <code>Description</code>
Parameters needs to be implemented. The functionality implied by the
other <code>ControllerTrust.Challenge.{i}.</code> Parameters needs to be
implemented, but does not have to be exposed through the data model.</p>
<p>A Controller that sends a Get Message on
<code>Device.ControllerTrust.Challenge.{i}.</code> will receive all
entries and Parameters that are allowed for its current assigned Role.
In the simplest case, this will be a single entry and only Alias and
Description will be supplied for that entry. It is important to restrict
visibility to all other implemented Parameters to highly trusted Roles,
if at all.</p>
<p>The Controller can display the value of <code>Description</code> to
the user and allow the user to indicate they want to request the
described challenge. If multiple entries were returned, the user can be
asked to select which challenge they want to request, based on the
description. An example of a description might be “Request
administrative privileges” or “Request guest privilege”.</p>
<p>When the user indicates to the Controller which challenge they want,
the Controller sends <code>RequestChallenge()</code> with the Path Name
of the <code>Challenge</code> Object Instance associated with the
desired <code>Description</code>. The Agent replies with the associated
<code>Instruction</code>, <code>InstructionType</code>,
<code>ValueType</code> and an auto-generated <code>ChallengeID</code>.
The Controller presents the value of <code>Instruction</code> to the
user (in a manner appropriate for <code>InstructionType</code>).
Examples of an instruction might be “Enter passphrase printed on bottom
of device” or “Enter PIN sent to registered email address”. The user
enters a string per the instructions, and the Controller sends this
value together with the <code>ChallengeID</code> in
<code>ChallengeResponse()</code>.</p>
<p>If the returned value matches <code>Value</code>, the Agent gives a
successful response - otherwise it returns an unsuccessful response. If
successful, the <code>ControllerTrust.Challenge.{i}.Role</code> replaces
an <code>UntrustedRole</code> in
<code>Controller.{i}.AssignedRole</code> or is appended to any other
<code>Controller.{i}.AssignedRole</code> value.</p>
<p>The number of times a <code>ControllerTrust.Challenge.{i}.</code>
entry can be consecutively failed (across all Controllers, without
intermediate success) is defined by <code>Retries</code>. Once the
number of failed consecutive attempts equals <code>Retries</code>, the
<code>ControllerTrust.Challenge.{i}.</code> cannot be retried until
after <code>LockoutPeriod</code> has expired.</p>
<p>Type values other than <code>Passphrase</code> can be used and
defined to trigger custom mechanisms, such as requests for emailed or
SMS-provided PINs.</p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:certificate-management">8.9.6 Certificate Management</h3>
<p>If an Agent wants to allow certificates associated with Controllers
and CAs to be exposed through USP, the Agent can implement the
<code>Controller.{i}.Credential</code> and
<code>ControllerTrust.Credential.{i}.Credential</code> Parameters, which
require implementation of the <code>LocalAgent.Certificate.</code>
Object. Allowing management of these certificates through USP can be
accomplished by implementing <code>LocalAgent.AddCertificate()</code>,
<code>Controller.{i}.AddMyCertificate()</code> and
<code>Certificate.{i}.Delete()</code> commands.</p>
<p>To allow a Controller to check whether the Agent has correct
certificates, the <code>Certificate.{i}.GetFingerprint()</code> command
can be implemented.</p>
<h3 class="auto-hoverlink" data-info="header"
id="sec:application-of-modified-parameters">8.9.7 Application of
Modified Parameters</h3>
<p>It is possible that various Parameters related to authentication and
authorization may change that would impact cached encrypted sessions and
Role permissions for Controllers. Example of such Parameters include
<code>Controller.{i}.AssignedRole</code>,
<code>Controller.{i}.Credential</code>,
<code>ControllerTrust.Role.</code> definition of a Role, and
<code>ControllerTrust.Credential.{i}.Role</code>.</p>
<p>There is no expectation that an Agent will apply these changes to
cached sessions. It is up to the Agent to determine whether or not it
will detect these changes and flush cached session information. However,
it is expected that a reboot will clear all cached session
information.</p>
<h1 class="annex1 auto-hoverlink" data-info="header"
id="sec:bulk-data-collection">Annex A: Bulk Data Collection</h1>
<p><em>Note: This Annex has been re-written in the 1.2 version of the
USP specification to include the previously-defined USP Event
Notification aspects of Bulk Data Collection and the new MQTT aspects of
Bulk Data Collection, in addition to the already defined HTTP Bulk Data
Collection mechanism.</em></p>
<p>This section discusses the Theory of Operation for USP specific
mechanisms related to the collection and transfer of bulk data using
either HTTP, MQTT, or USP Event Notifications. This includes an
explanation of how the Agent can be configured to enable the collection
of bulk data using HTTP, MQTT, or USP Event Notifications via the
BulkData Objects, which are defined in the Device:2 Data Model <span
class="citation" data-cites="TR-181"><a href="#ref-TR-181"
role="doc-biblioref">[3]</a></span>.</p>
<h2 class="annex2 auto-hoverlink" data-info="header"
id="sec:introduction-1">A.1 Introduction</h2>
<p>The general concept behind the USP Bulk Data collection mechanism is
that a USP Controller can configure an Agent to consistently deliver a
bulk data report at a specific interval. For large populations, this is
a more efficient mechanism when compared to the alternative of polling
each individual Agent for the data. There are four key aspects of
configuring the bulk data collection mechanism on an Agent:</p>
<ul>
<li><p><strong>What data needs to be collected</strong> :: The set of
Object/Parameter Path Names that dictate the set of Parameters that will
be included in each Bulk Data report. Anything included in this set
should be considered a filter that is applied against the Instantiated
Data Model at the time of report generation, which means that the
generation of the report is not contingent upon the Path Name being
present in the Instantiated Data Model at the time of report
generation.</p></li>
<li><p><strong>How often does the data need to be collected</strong> ::
The interval and time reference that dictates the frequency and cycle of
report generation. For example, the interval could be set to 15 minutes
while the time reference could be set to 42 minutes past 1 AM, which
would mean that the report is generated every 15 minutes at 42 past the
hour, 57 past the hour, 12 past the hour, and 27 past the hour.</p></li>
<li><p><strong>Where does the data need to be sent</strong> :: The
destination of where the report needs to be delivered after it has been
generated. This is specific to the Bulk Data collection mechanism being
used: HTTP vs MQTT vs USP Event Notification.</p></li>
<li><p><strong>How does the data get sent</strong> :: The protocol used
to send the data across the wire, the encoding of the data, and the
format of the data. From a Protocol perspective, the HTTP Bulk Data
collection mechanism utilizes either the HTTP or HTTPS protocols, the
MQTT Bulk Data Collection mechanism utilizes the MQTT protocol, and the
USPEventNotif Bulk Data collection mechanism utilizes the existing USP
communications channel related to the USP Controller that owns the bulk
data profile. From a data encoding perspective, both Bulk Data
collection mechanisms support the <em>CSV</em> and <em>JSON</em> options
as described later. From a data formatting perspective, both Bulk Data
collection mechanisms support the <em>Object Hierarchy</em> and <em>Name
Value Pair</em> report formats, also described later.</p></li>
</ul>
<p>The Bulk Data collection mechanism is configured within an Agent by
creating a Bulk Data Profile. A Bulk Data Profile defines the
configuration of the four key aspects (as mentioned above) for a given
Bulk Data Report. Meaning, the Bulk Data Profile defines the protocol to
use (HTTP vs MQTT vs USPEventNotif), the data encoding to use (CSV vs
JSON), the report format to use (Object Hierarchy vs Name Value Pair),
the destination of the report, the frequency of the report generation,
and the set of Parameters to include in the report. Furthermore, the
Bulk Data Profile has a <code>Controller</code> Parameter that is a
read-only Parameter and is set by the Agent based on the Controller that
created the Bulk Data Profile. The Controller Parameter represents the
owner of the Profile, which is used when determining permissions. When
the Agent generates the Bulk Data Report it uses the permissions
associated with the referenced Controller to determine what is included
in the Report (Objects and Parameters that fail the permissions check
are simply filtered out of the Report).</p>
<p><em>Note: When a Bulk Data Collection Profile is either created or
updated the Agent performs validation checks for the associated Objects
and Parameters against the Supported Data Model at the time of the
operation.</em></p>
<p><em>Note: When a Bulk Data Collection Report is generated the Agent
performs permission checks for the associated Objects and parameters
against the Instantiated Data Model, filtering out any Object instances
or Parameters that are not present at that time.</em></p>
<h2 class="annex2 auto-hoverlink" data-info="header"
id="sec:http-bulk-data-collection">A.2 HTTP Bulk Data Collection</h2>
<p>The Bulk Data Collection mechanism that utilizes an out-of-band
HTTP/HTTPS communications mechanism for delivering the Bulk Data
Report.</p>
<h3 class="annex3 auto-hoverlink" data-info="header"
id="sec:enabling-httphttps-bulk-data-communication">A.2.1 Enabling
HTTP/HTTPS Bulk Data Communication</h3>
<p>HTTP/HTTPS communication between the Agent and Bulk Data Collector is
enabled by either configuring an existing <code>BulkData.Profile</code>
Object Instance for the HTTP/HTTPS transport protocol or adding and
configuring a new <code>BulkData.Profile</code> Object Instance using
the <a href="#sec:add" class="heading">Add Message</a>. For example:</p>
<pre><code>.BulkData.Profile.1
.BulkData.Profile.1.Enable=true
.BulkData.Profile.1.Protocol = &quot;HTTP&quot;
.BulkData.Profile.1.ReportingInterval = 300
.BulkData.Profile.1.TimeReference = &quot;0001-01-01T00:00:00Z&quot;
.BulkData.Profile.1.HTTP.URL =  &quot;https://bdc.acme.com/somedirectory&quot;
.BulkData.Profile.1.HTTP.Username = &quot;username&quot;
.BulkData.Profile.1.HTTP.Password = &quot;password&quot;
.BulkData.Profile.1.HTTP.Method = &quot;POST&quot;
.BulkData.Profile.1.HTTP.UseDateHeader = true</code></pre>
<p>The configuration above defines a profile that transfers data from
the Agent to the Bulk Data Collector using secured HTTP. In addition the
Agent will provide authentication credentials (username, password) to
the Bulk Data Collector, if requested by the Bulk Data Collector.
Finally, the Agent establishes a communication session with the Bulk
Data Collector every 300 seconds in order to transfer the data defined
by the <code>.BulkData.Report.</code> Object Instance.</p>
<p>Once the communication session is established between the Agent and
Bulk Data Collector the data is transferred from the Agent using the
POST HTTP method with a HTTP Date header and no compression.</p>
<p><strong><span id="r-bulk.0"
class="auto-hoverlink">R-BULK.0</span></strong> - In many scenarios
Agents will utilize “chunked” transfer encoding. As such, the Bulk Data
Collector MUST support the HTTP transfer-coding value of “chunked”.</p>
<h3 class="annex3 auto-hoverlink" data-info="header"
id="sec:use-of-the-uri-query-parameters">A.2.2 Use of the URI Query
Parameters</h3>
<p>The HTTP Bulk Data transfer mechanism allows Parameters to be used as
HTTP URI query parameters. This is useful when Bulk Data Collector
utilizes the specific parameters that the Agent reports for processing
(e.g., logging, locating directories) without the need for the Bulk Data
Collector to parse the data being transferred.</p>
<p><strong><span id="r-bulk.1"
class="auto-hoverlink">R-BULK.1</span></strong> - The Agent MUST
transmit the device’s Manufacturer OUI, Product Class and Serial Number
or the USP Endpoint ID as part of the URI query parameters. The data
model Parameters are encoded as:</p>
<pre><code>.DeviceInfo.ManufacturerOUI -&gt; oui
.DeviceInfo.ProductClass  -&gt; pc
.DeviceInfo.SerialNumber  -&gt; sn
.LocalAgent.EndpointID -&gt; eid</code></pre>
<p>As such, the values of the device’s OUI, Serial Number and Product
Class are formatted in the HTTP request URI as follows:</p>
<pre><code>POST https://&lt;bulk data collector url&gt;?oui=00256D&amp;pc=Z&amp;sn=Y</code></pre>
<p>If the USP Endpoint ID is used the HTTP request URI is formatted
as:</p>
<pre><code>POST https://&lt;bulk data collector url&gt;?eid=os::000256:asdfa99384</code></pre>
<p><em>Note: If the USP Endpoint ID should be transmitted together with
the device’s Manufacturer OUI, Product Class and Serial Number (e.g. to
distinguish multiple bulk data collection instances on the same device),
then the USP Endpoint ID has to be configured as additional URI
parameter in the
<code>.BulkData.Profile.{i}.HTTP.RequestURIParameter.{i}.</code>
table.</em></p>
<p>Configuring the URI query parameters for other Parameters requires
that instances of a
<code>.BulkData.Profile.{i}.HTTP.RequestURIParameter.{i}.</code> Object
Instance be created and configured with the requested parameters. The
additional parameters are appended to the required URI query
parameters.</p>
<p>Using the example to add the device’s current local time to the
required URI parameters, the HTTP request URI would be as follows:</p>
<pre><code>POST https://&lt;bulk data collector url&gt;?oui=00256D&amp;pc=Z&amp;sn=Y&amp;ct=2015-11-01T11:12:13Z</code></pre>
<p>By setting the following Parameters using the Add Message as
follows:</p>
<pre><code>.BulkData.Profile.1.HTTP.RequestURIParameter 1.Name =&quot;ct&quot;
.BulkData.Profile.1.HTTP.RequestURIParameter.1.Reference =&quot;Device.Time.CurrentLocalTime&quot;</code></pre>
<h3 class="annex3 auto-hoverlink" data-info="header"
id="sec:use-of-http-status-codes">A.2.3 Use of HTTP Status Codes</h3>
<p>The Bulk Data Collector uses standard HTTP status codes, defined in
the HTTP specification, to inform the Agent whether a bulk data transfer
was successful. The HTTP status code is set in the response header by
the Bulk Data Collector. For example, “<code>200 OK</code>” status code
indicates an upload was processed successfully,
“<code>202 Accepted</code>” status code indicates that the request has
been accepted for processing, but the processing has not been completed,
“<code>401 Unauthorized</code>” status code indicates user
authentication failed and a “<code>500 Internal Server Error</code>”
status code indicates there is an unexpected system error.</p>
<h4 class="annex4 auto-hoverlink" data-info="header"
id="sec:http-retry-mechanism">A.2.3.1 HTTP Retry Mechanism</h4>
<p><strong><span id="r-bulk.2"
class="auto-hoverlink">R-BULK.2</span></strong> - When the Agent
receives an unsuccessful HTTP status code and the HTTP retry behavior is
enabled, the Agent MUST try to redeliver the data. The retry mechanism
employed for the transfer of bulk data using HTTP uses the same
algorithm as is used for <a href="#sec:responses-and-retry"
class="heading">USP Notify retries</a>.</p>
<p>The retry interval range is controlled by two Parameters, the minimum
wait interval and the interval multiplier, each of which corresponds to
a data model Parameter, and which are described in the table below. The
factory default values of these Parameters MUST be the default values
listed in the Default column. They MAY be changed by a Controller with
the appropriate permissions at any time.</p>
<table>
<colgroup>
<col style="width: 26%" />
<col style="width: 18%" />
<col style="width: 21%" />
<col style="width: 34%" />
</colgroup>
<thead>
<tr class="header">
<th style="text-align: right;">Descriptive Name</th>
<th style="text-align: center;">Symbol</th>
<th style="text-align: center;">Default</th>
<th style="text-align: left;">Data Model Parameter Name</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: right;">Minimum wait interval</td>
<td style="text-align: center;">m</td>
<td style="text-align: center;">5 seconds</td>
<td
style="text-align: left;"><code>Device.BulkData.Profile.{i}.HTTP.RetryMinimumWaitInterval</code></td>
</tr>
<tr class="even">
<td style="text-align: right;">Interval multiplier</td>
<td style="text-align: center;">k</td>
<td style="text-align: center;">2000</td>
<td
style="text-align: left;"><code>Device.BulkData.Profile.{i}.HTTP.RetryIntervalMultiplier</code></td>
</tr>
</tbody>
</table>
<table>
<colgroup>
<col style="width: 29%" />
<col style="width: 29%" />
<col style="width: 40%" />
</colgroup>
<thead>
<tr class="header">
<th style="text-align: right;">Retry Count</th>
<th style="text-align: center;">Default Wait Interval Range (min-max
seconds)</th>
<th style="text-align: left;">Actual Wait Interval Range (min-max
seconds)</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: right;">#1</td>
<td style="text-align: center;">5-10</td>
<td style="text-align: left;">m - m.(k/1000)</td>
</tr>
<tr class="even">
<td style="text-align: right;">#2</td>
<td style="text-align: center;">10-20</td>
<td style="text-align: left;">m.(k/1000) - m.(k/1000)2</td>
</tr>
<tr class="odd">
<td style="text-align: right;">#3</td>
<td style="text-align: center;">20-40</td>
<td style="text-align: left;">m.(k/1000)2 - m.(k/1000)3</td>
</tr>
<tr class="even">
<td style="text-align: right;">#4</td>
<td style="text-align: center;">40-80</td>
<td style="text-align: left;">m.(k/1000)3 - m.(k/1000)4</td>
</tr>
<tr class="odd">
<td style="text-align: right;">#5</td>
<td style="text-align: center;">80-160</td>
<td style="text-align: left;">m.(k/1000)4 - m.(k/1000)5</td>
</tr>
<tr class="even">
<td style="text-align: right;">#6</td>
<td style="text-align: center;">160-320</td>
<td style="text-align: left;">m.(k/1000)5 - m.(k/1000)6</td>
</tr>
<tr class="odd">
<td style="text-align: right;">#7</td>
<td style="text-align: center;">320-640</td>
<td style="text-align: left;">m.(k/1000)6 - m.(k/1000)7</td>
</tr>
<tr class="even">
<td style="text-align: right;">#8</td>
<td style="text-align: center;">640-1280</td>
<td style="text-align: left;">m.(k/1000)7 - m.(k/1000)8</td>
</tr>
<tr class="odd">
<td style="text-align: right;">#9</td>
<td style="text-align: center;">1280-2560</td>
<td style="text-align: left;">m.(k/1000)8 - m.(k/1000)9</td>
</tr>
<tr class="even">
<td style="text-align: right;">#10 and subsequent</td>
<td style="text-align: center;">2560-5120</td>
<td style="text-align: left;">m.(k/1000)9 - m.(k/1000)10</td>
</tr>
</tbody>
</table>
<p><strong><span id="r-bulk.3"
class="auto-hoverlink">R-BULK.3</span></strong> - Beginning with the
tenth retry attempt, the Agent MUST choose from the fixed maximum range.
The Agent will continue to retry a failed bulk data transfer until it is
successfully delivered or until the next reporting interval for the data
transfer becomes effective.</p>
<p><strong><span id="r-bulk.4"
class="auto-hoverlink">R-BULK.4</span></strong> - Once a bulk data
transfer is successfully delivered, the Agent MUST reset the retry count
to zero for the next reporting interval.</p>
<p><strong><span id="r-bulk.5"
class="auto-hoverlink">R-BULK.5</span></strong> - If a reboot of the
Agent occurs, the Agent MUST reset the retry count to zero for the next
bulk data transfer.</p>
<h4 class="annex4 auto-hoverlink" data-info="header"
id="sec:processing-of-content-for-failed-report-transmissions">A.2.3.2
Processing of Content for Failed Report Transmissions</h4>
<p>When the content (report) cannot be successfully transmitted,
including retries, to the data collector, the
<code>NumberOfRetainedFailedReports</code> Parameter of the
<code>BulkData.Profile</code> Object Instance defines how the content
should be disposed based on the following rules:</p>
<ul>
<li>When the value of the <code>NumberOfRetainedFailedReports</code>
Parameter is greater than <code>0</code>, then the report for the
current reporting interval is appended to the list of failed reports.
How the content is appended is dependent on the type of encoding (e.g.,
CSV, JSON) and is described further in corresponding encoding
section.</li>
<li>If the value of the <code>NumberOfRetainedFailedReports</code>
Parameter is <code>-1</code>, then the Agent will retain as many failed
reports as possible.</li>
<li>If the value of the NumberOfRetainedFailedReports Parameter is
<code>0</code>, then failed reports are not to be retained for
transmission in the next reporting interval.</li>
<li>If the Agent cannot retain the number of failed reports from
previous reporting intervals while transmitting the report of the
current reporting interval, then the oldest failed reports are deleted
until the Agent is able to transmit the report from the current
reporting interval.</li>
<li>If the value <code>BulkData.Profile</code> Object Instance’s
<code>EncodingType</code> Parameter is modified any outstanding failed
reports are deleted.</li>
</ul>
<h3 class="annex3 auto-hoverlink" data-info="header"
id="sec:use-of-tls-and-tcp">A.2.4 Use of TLS and TCP</h3>
<p>The use of TLS to transport the HTTP Bulk Data is RECOMMENDED,
although the protocol MAY be used directly over a TCP connection
instead. If TLS is not used, some aspects of security are sacrificed.
Specifically, TLS provides confidentiality and data integrity, and
allows certificate-based authentication in lieu of shared secret-based
authentication.</p>
<p><strong><span id="r-bulk.6"
class="auto-hoverlink">R-BULK.6</span></strong> - Certain restrictions
on the use of TLS and TCP are defined as follows:</p>
<ul>
<li>The Agent MUST support TLS version 1.2 or later (with backward
compatibility to TLS 1.2).</li>
<li>If the Collection Server URL has been specified as an HTTPS URL, the
Agent MUST establish secure connections to the Collection Server, and
MUST start the TLS session negotiation with TLS 1.2 or later.</li>
</ul>
<p><em>Note: If the Collection Server does not support TLS 1.2 or higher
with a cipher suite supported by the Agent, it may not be possible for
the Agent to establish a secure connection to the Collection
Server.</em></p>
<p><em>Note: TLS_RSA_WITH_AES_128_CBC_SHA is the only mandatory TLS 1.2
cipher suite.</em></p>
<ul>
<li>The Agent SHOULD use the <span class="citation"
data-cites="RFC6066"><a href="#ref-RFC6066"
role="doc-biblioref">[17]</a></span> Server Name TLS extension to send
the host portion of the Collection Server URL as the server name during
the TLS handshake.</li>
<li>If TLS 1.2 (or a later version) is used, the Agent MUST authenticate
the Collection Server using the certificate provided by the Collection
Server. Authentication of the Collection Server requires that the Agent
MUST validate the certificate against a root certificate. To validate
against a root certificate, the Agent MUST contain one or more trusted
root certificates that are either pre-loaded in the Agent or provided to
the Agent by a secure means outside the scope of this specification. If
as a result of an HTTP redirect, the Agent is attempting to access a
Collection Server at a URL different from its pre-configured Collection
Server URL, the Agent MUST validate the Collection Server certificate
using the redirected Collection Server URL rather than the
pre-configured Collection Server URL.</li>
<li>If the host portion of the Collection Server URL is a DNS name, this
MUST be done according to the principles of RFC 6125 <span
class="citation" data-cites="RFC6125"><a href="#ref-RFC6125"
role="doc-biblioref">[18]</a></span>, using the host portion of the
Collection Server URL as the reference identifier.</li>
<li>If the host portion of the Collection Server URL is an IP address,
this MUST be done by comparing the IP address against any presented
identifiers that are IP addresses.</li>
</ul>
<p><em>Note: the terms “reference identifier” and “presented identifier”
are defined in RFC 6125 <span class="citation" data-cites="RFC6125"><a
href="#ref-RFC6125" role="doc-biblioref">[18]</a></span>.</em></p>
<p><em>Note: wildcard certificates are permitted as described in RFC
6125 <span class="citation" data-cites="RFC6125"><a href="#ref-RFC6125"
role="doc-biblioref">[18]</a></span>.</em></p>
<ul>
<li>An Agent capable of obtaining absolute time SHOULD wait until it has
accurate absolute time before contacting the Collection Server. If a
Agent for any reason is unable to obtain absolute time, it can contact
the Collection Server without waiting for accurate absolute time. If a
Agent chooses to contact the Collection Server before it has accurate
absolute time (or if it does not support absolute time), it MUST ignore
those components of the Collection Server certificate that involve
absolute time, e.g. not-valid-before and not-valid-after certificate
restrictions.</li>
<li>Support for Agent authentication using client-side certificates is
NOT RECOMMENDED. Instead, the Collection Server SHOULD authenticate the
Agent using HTTP basic or digest authentication to establish the
identity of a specific Agent.</li>
</ul>
<h3 class="annex3 auto-hoverlink" data-info="header"
id="sec:bulk-data-encoding-requirements">A.2.5 Bulk Data Encoding
Requirements</h3>
<p>When utilizing the HTTP Bulk Data collection option, the encoding
type is sent as a media type within the report. For CSV the media type
is <code>text/csv</code> as specified in RFC 4180 <span class="citation"
data-cites="RFC4180"><a href="#ref-RFC4180"
role="doc-biblioref">[32]</a></span> and for JSON the media type is
<code>application/json</code> as specified in RFC 7159 <span
class="citation" data-cites="RFC7159"><a href="#ref-RFC7159"
role="doc-biblioref">[35]</a></span>. For example, a CSV encoded report
using <code>charset=UTF-8</code> would have the following Content-Type
header:</p>
<pre><code>Content-Type: text/csv; charset=UTF-8</code></pre>
<p><strong><span id="r-bulk.7"
class="auto-hoverlink">R-BULK.7</span></strong> - The
“<code>media-type</code>” field and “<code>charset</code>” Parameters
MUST be present in the Content-Type header.</p>
<p>In addition the report format that was used for encoding the report
is included as an HTTP custom header with the following format:</p>
<pre><code>BBF-Report-Format: &lt;ReportFormat&gt;</code></pre>
<p>The &lt;ReportFormat&gt; field is represented as a token.</p>
<p>For example a CSV encoded report using a ReportFormat for
ParameterPerRow would have the following BBF-Report-Format header:</p>
<pre><code>BBF-Report-Format: &quot;ParameterPerRow&quot;</code></pre>
<p><strong><span id="r-bulk.8"
class="auto-hoverlink">R-BULK.8</span></strong> - The BBF-Report-Format
custom header MUST be present when transferring data to the Bulk Data
Collector from the Agent using HTTP/HTTPS.</p>
<h2 class="annex2 auto-hoverlink" data-info="header"
id="sec:mqtt-bulk-data-collection">A.3 MQTT Bulk Data Collection</h2>
<p>The Bulk Data Collection mechanism that utilizes an out-of-band MQTT
communications mechanism for delivering the Bulk Data Report.</p>
<h3 class="annex3 auto-hoverlink" data-info="header"
id="sec:enabling-mqtt-bulk-data-communication">A.3.1 Enabling MQTT Bulk
Data Communication</h3>
<p>Bulk Data communications that utilizes MQTT for transferring the Bulk
Data Report between the Agent and a Bulk Data Collector, is enabled by
either configuring an existing <code>BulkData.Profile</code> Object
Instance for the MQTT transport protocol or adding and configuring a new
<code>BulkData.Profile</code> Object Instance using the <a
href="#sec:add" class="heading">Add Message</a>. For example:</p>
<pre><code>.BulkData.Profile.1
.BulkData.Profile.1.Enable = true
.BulkData.Profile.1.Name = &quot;MQTT Profile 1&quot;
.BulkData.Profile.1.Protocol = &quot;MQTT&quot;
.BulkData.Profile.1.EncodingType = &quot;JSON&quot;
.BulkData.Profile.1.ReportingInterval = 300
.BulkData.Profile.1.TimeReference = &quot;0001-01-01T00:00:00Z&quot;
.BulkData.Profile.1.MQTT.Reference =  &quot;Device.MQTT.Client.1&quot;
.BulkData.Profile.1.MQTT.PublishTopic = &quot;/bulkdata&quot;
.BulkData.Profile.1.MQTT.PublishQoS = 1
.BulkData.Profile.1.MQTT.PublishRetain = false</code></pre>
<p>The configuration above defines a profile that transfers data from
the Agent to a Bulk Data Collector via the MQTT protocol. The Agent
utilizes the referenced MQTT Client instance to determine the MQTT
broker for this Bulk Data Collection Profile. The Agent sends the Bulk
Data Report to the reference MQTT Broker by issuing an MQTT PUBLISH
message to the PublishTopic every 300 seconds (ReportingInterval). The
Bulk Data Collector would subscribe to the PublishTopic in order to
receive the Bulk Data Reports.</p>
<h3 class="annex3 auto-hoverlink" data-info="header"
id="sec:determining-successful-transmission">A.3.2 Determining
Successful Transmission</h3>
<p>Delivering a Bulk Data Collection report using MQTT means that
successful transmission of the report is tied to the successful delivery
of the MQTT PUBLISH message, which is determined by the PublishQoS
configured as part of the Bulk Data Collection Profile.</p>
<h4 class="annex4 auto-hoverlink" data-info="header"
id="sec:retrying-failed-transmissions">A.3.2.1 Retrying Failed
Transmissions</h4>
<p>Delivering a Bulk Data Collection report using MQTT means that any
failed transmissions are retried based on the referenced MQTT Client and
the associated QoS value contained within the MQTT PUBLISH message,
which is determined by the PublishQoS parmater. Furthermore, the
CleanSession (MQTT 3.1 and MQTT 3.1.1) and CleanStart (MQTT 5.0) flags
determine if unacknowledged PUBLISH messages are re-delivered on client
reconnect. For MQTT 3.1 there is also the MessageRetryTime defined in
the referenced MQTT Client that determines how frequently an
unacknowledged PUBLISH message should be retried.</p>
<h4 class="annex4 auto-hoverlink" data-info="header"
id="sec:processing-of-content-for-failed-report-transmissions-1">A.3.2.2
Processing of Content for Failed Report Transmissions</h4>
<p>When the content (report) cannot be successfully transmitted,
including retries, to the MQTT broker, the
<code>NumberOfRetainedFailedReports</code> Parameter of the
<code>BulkData.Profile</code> Object Instance defines how the content
should be disposed based on the following rules:</p>
<ul>
<li>When the value of the <code>NumberOfRetainedFailedReports</code>
Parameter is greater than <code>0</code>, then the report for the
current reporting interval is appended to the list of failed reports.
How the content is appended is dependent on the type of encoding (e.g.,
CSV, JSON) and is described further in corresponding encoding
section.</li>
<li>If the value of the <code>NumberOfRetainedFailedReports</code>
Parameter is <code>-1</code>, then the Agent will retain as many failed
reports as possible.</li>
<li>If the value of the NumberOfRetainedFailedReports Parameter is
<code>0</code>, then failed reports are not to be retained for
transmission in the next reporting interval.</li>
<li>If the Agent cannot retain the number of failed reports from
previous reporting intervals while transmitting the report of the
current reporting interval, then the oldest failed reports are deleted
until the Agent is able to transmit the report from the current
reporting interval.</li>
<li>If the value <code>BulkData.Profile</code> Object Instance’s
<code>EncodingType</code> Parameter is modified any outstanding failed
reports are deleted.</li>
</ul>
<h3 class="annex3 auto-hoverlink" data-info="header"
id="sec:bulk-data-encoding-requirements-1">A.3.3 Bulk Data Encoding
Requirements</h3>
<p>When utilizing the MQTT Bulk Data collection option with a MQTT 5.0
Client connection, the encoding type is sent as a media type within the
MQTT PUBLISH message header and the Content Type property. For CSV the
media type is <code>text/csv</code> as specified in RFC 4180 <span
class="citation" data-cites="RFC4180"><a href="#ref-RFC4180"
role="doc-biblioref">[32]</a></span> and for JSON the media type is
<code>application/json</code> as specified in RFC 7159 <span
class="citation" data-cites="RFC7159"><a href="#ref-RFC7159"
role="doc-biblioref">[35]</a></span>. For example, a CSV encoded report
using <code>charset=UTF-8</code> would have the following Content Type
property:</p>
<pre><code>text/csv; charset=UTF-8</code></pre>
<p><strong><span id="r-bulk.8a"
class="auto-hoverlink">R-BULK.8a</span></strong> - The
“<code>media-type</code>” field and “<code>charset</code>” parameters
MUST be present in the Content Type property when using MQTT 5.0.</p>
<p>When utilizing the MQTT Bulk Data collection option with a MQTT 3.1
or MQTT 3.1.1 client connection, the encoding type is not sent in the
MQTT PUBLISH message; instead the receiving Bulk Data Collector will
need to know how the <code>.BulkData.Profile</code> Object Instance is
configured.</p>
<p>In addition the data layout is not included in the MQTT PUBLISH
message; instead the receiving Bulk Data Collector will need to know how
the <code>.BulkData.Profile.{i}.CSVEncoding.ReportFormat</code> or
<code>.BulkData.Profile.{i}.JSONEncoding.ReportFormat</code> Parameter
is configured.</p>
<h2 class="annex2 auto-hoverlink" data-info="header"
id="sec:uspeventnotif-bulk-data-collection">A.4 USPEventNotif Bulk Data
Collection</h2>
<p>The Bulk Data Collection mechanism that utilizes the existing USP
communications channel for delivering the Bulk Data Report via a <a
href="#sec:notify" class="heading">Notify Message</a> that contains a
Push! Event.</p>
<h3 class="annex3 auto-hoverlink" data-info="header"
id="sec:enabling-uspeventnotif-bulk-data-communication">A.4.1 Enabling
USPEventNotif Bulk Data Communication</h3>
<p>Bulk Data communications using a USP Event notification that utilizes
the <a href="#sec:notify" class="heading">Notify Message</a> between the
Agent and a Controller, acting as a Bulk Data Collector, is enabled by
either configuring an existing <code>BulkData.Profile</code> Object
Instance for the USPEventNotif transport protocol or adding and
configuring a new <code>BulkData.Profile</code> Object Instance using
the <a href="#sec:add" class="heading">Add Message</a>. For example:</p>
<pre><code>.BulkData.Profile.1
.BulkData.Profile.1.Enable = true
.BulkData.Profile.1.Name = &quot;USP Notif Profile 1&quot;
.BulkData.Profile.1.Protocol = &quot;USPEventNotif&quot;
.BulkData.Profile.1.EncodingType = &quot;JSON&quot;
.BulkData.Profile.1.ReportingInterval = 300
.BulkData.Profile.1.TimeReference = &quot;0001-01-01T00:00:00Z&quot;</code></pre>
<p>The configuration above defines a profile that transfers data from
the Agent to a Controller that is acting as the Bulk Data Collector. The
Controller that receives an Event notification is dictated by the
Agent’s currently defined Subscriptions <a
href="#sec:notifications-and-subscriptions"
class="heading">Notifications and Subscription Mechanism</a>. The Agent
utilizes the existing communications session with the Controller acting
as the Bulk Data Collector every 300 seconds in order to transfer the
data defined by the <code>.BulkData.Profile</code> Object Instance.</p>
<p>The data is transferred from the Agent using the USP Notify Message
and a <code>.BulkData.Profile.1.Push!</code> Event notification.</p>
<h3 class="annex3 auto-hoverlink" data-info="header"
id="sec:determining-successful-transmission-1">A.4.2 Determining
Successful Transmission</h3>
<p>Delivering a Bulk Data Collection report using the USP Notify Message
and a <code>.BulkData.Profile.1.Push!</code> Event notification means
that successful transmission of the report is tied to the successful
delivery of the notification itself <a href="#sec:responses-and-retry"
class="heading">Responses to Notifications and Notification
Retry</a>.</p>
<h4 class="annex4 auto-hoverlink" data-info="header"
id="sec:retrying-failed-transmissions-1">A.4.2.1 Retrying Failed
Transmissions</h4>
<p>Delivering a Bulk Data Collection report using the USP Notify Message
and a <code>.BulkData.Profile.1.Push!</code> Event notification means
that any failed transmissions are retried based on the notification
retry requirements <a href="#r-not.1" class="requirement">R-NOT.1</a>
through <a href="#r-not.4" class="requirement">R-NOT.4</a> <a
href="#sec:responses-and-retry" class="heading">Responses to
Notifications and Notification Retry</a>.</p>
<p>Furthermore, the <code>NumberOfRetainedFailedReports</code> Parameter
of the <code>BulkData.Profile</code> Object Instance does not pertain to
the USPEventNotif Bulk Data Collection mechanism as each report is
wholly contained within a USP Notify Message. This means that the
notification retry mechanism will determine the life of each individual
failed report, and that each reporting interval will generate a new
report that is delivered via a new USP Notify Message.</p>
<h3 class="annex3 auto-hoverlink" data-info="header"
id="sec:bulk-data-encoding-requirements-2">A.4.3 Bulk Data Encoding
Requirements</h3>
<p>When utilizing the USPEventNotif Bulk Data collection option, the
encoding type is not sent in the USP Event notification; instead the
receiving Controller will need to know how the
<code>.BulkData.Profile</code> Object Instance is configured.</p>
<p>In addition the data layout is not included in the USP Event
notification; instead the receiving Controller will need to know how the
<code>.BulkData.Profile.{i}.CSVEncoding.ReportFormat</code> or
<code>.BulkData.Profile.{i}.JSONEncoding.ReportFormat</code> Parameter
is configured.</p>
<h2 class="annex2 auto-hoverlink" data-info="header"
id="sec:using-wildcards-to-reference-object-instances-in-the-report">A.5
Using Wildcards to Reference Object Instances in the Report</h2>
<p>When the Agent supports the use of the Wildcard value “*” in place of
instance identifiers for the Reference Parameter, then all Object
Instances of the referenced Parameter are encoded. For example to encode
the “<code>BroadPktSent</code>” Parameter for all Object Instances of
the MoCA Interface Object the following will be configured:</p>
<pre><code>    .BulkData.Profile.1.Parameter.1.Name =  &quot;&quot;
    .BulkData.Profile.1.Parameter.1.Reference =  &quot;Device.MoCA.Interface.*.Stats.BroadPktSent&quot;</code></pre>
<h2 class="annex2 auto-hoverlink" data-info="header"
id="sec:using-alternative-names-in-the-report">A.6 Using Alternative
Names in the Report</h2>
<p>Alternative names can be defined for the Parameter name in order to
shorten the name of the Parameter. For example instead of encoding the
full Parameter name
“<code>Device.MoCA.Interface.1.Stats.BroadPktSent</code>” could be
encoded with a shorter name “<code>BroadPktSent</code>”. This allows the
encoded data to be represented using the shorter name. This would be
configured as:</p>
<pre><code>.BulkData.Profile.1.Parameter.1.Name =  &quot;BroadPktSent&quot;
.BulkData.Profile.1.Parameter.1.Reference =  &quot;Device.MoCA.Interface.1.Stats.BroadPktSent&quot;</code></pre>
<p>In the scenario where there are multiple instances of a Parameter
(e.g., “<code>Device.MoCA.Interface.1.Stats.BroadPktSent</code>”,
“<code>Device.MoCA.Interface.2.Stats.BroadPktSent</code>”) in a Report,
the content of the Name parameter SHOULD be unique (e.g.,
<code>BroadPktSent.1</code>, <code>BroadPktSent.2</code>).</p>
<h4 class="annex4 auto-hoverlink" data-info="header"
id="sec:using-object-instance-wildcards-and-parameter-partial-paths-with-alternative-names">A.6.0.1
Using Object Instance Wildcards and Parameter Partial Paths with
Alternative Names</h4>
<p>Wildcards for Object Instances can be used in conjunction with the
use of alternative names by reflecting Object hierarchy of the value of
the Reference Parameter in the value of the Name Parameter.</p>
<p><strong><span id="r-bulk.9"
class="auto-hoverlink">R-BULK.9</span></strong> - When the value of the
Reference Parameter uses a wildcard for an instance identifier, the
value of the Name Parameter (as used in a report) MUST reflect the
wild-carded instance identifiers of the Parameters being reported on.
Specifically, the value of the Name Parameter MUST be appended with a
period (.) and then the instance identifier. If the value of the
Reference Parameter uses multiple wildcard then each wild-carded
instance identifier MUST be appended in order from left to right.</p>
<p>For example, for a device to report the Bytes Sent for the Associated
Devices of the device’s Wi-Fi Access Points the following would be
configured:</p>
<pre><code>.BulkData.Profile.1.Parameter.1.Name =  &quot;WiFi_AP_Assoc_BSent&quot;
.BulkData.Profile.1.Parameter.1.Reference = &quot;Device.WiFi.AccessPoint.*.AssociatedDevice.*.Stats.BytesSent&quot;</code></pre>
<p>Using this configuration a device that has 2 Wi-Fi Access Points
(with instance identifiers <code>1</code> and <code>3</code>) each with
2 Associated Devices (with instance identifiers <code>10</code> and
<code>11</code>), would contain a Report with following Parameter
names:</p>
<pre><code>WiFi_AP_Assoc_BSent.1.10
WiFi_AP_Assoc_BSent.1.11
WiFi_AP_Assoc_BSent.3.10
WiFi_AP_Assoc_BSent.3.11</code></pre>
<p>Object or Object Instance Paths can also be used to report all
Parameters of the associated Object.</p>
<p><strong><span id="r-bulk.10"
class="auto-hoverlink">R-BULK.10</span></strong> - When the value of the
Reference Parameter is an Object Path, the value of the Name Parameter
(as used in a report) MUST reflect the remainder of the Parameter Path.
Specifically, the value of Name Parameter MUST be appended with a “.”
and then the remainder of the Parameter Path.</p>
<p>For example, for a device to report the statistics of a Wi-Fi
associated device Object Instance the following would be configured:</p>
<pre><code>.BulkData.Profile.1.Parameter.1.Name = &quot;WiFi_AP1_Assoc10&quot;
.BulkData.Profile.1.Parameter.1.Reference = &quot;Device.WiFi.AccessPoint.1.AssociatedDevice.10.Stats.&quot;</code></pre>
<p>Using the configuration the device’s report would contain the
following Parameter names:</p>
<pre><code>WiFi_AP1_Assoc10.BytesSent
WiFi_AP1_Assoc10.BytesReceived
WiFi_AP1_Assoc10.PacketsSent
WiFi_AP1_Assoc10.PacketsReceived
WiFi_AP1_Assoc10.ErrorsSent
WiFi_AP1_Assoc10.RetransCount
WiFi_AP1_Assoc10.FailedRetransCount
WiFi_AP1_Assoc10.RetryCount
WiFi_AP1_Assoc10.MultipleRetryCount</code></pre>
<p>It is also possible for the value of the Reference Parameter to use
both wildcards for instance identifiers and be a partial Path Name. For
example, for device to report the statistics for the device’s Wi-Fi
associated device, the following would be configured:</p>
<pre><code>.BulkData.Profile.1.Parameter.1.Name = &quot;WiFi_AP_Assoc&quot;
.BulkData.Profile.1.Parameter.1.Reference = &quot;Device.WiFi.AccessPoint.*.AssociatedDevice.*.Stats.&quot;</code></pre>
<p>Using this configuration a device that has 1 Wi-Fi Access Point (with
instance identifier <code>1</code>) with 2 Associated Devices (with
instance identifiers <code>10</code> and <code>11</code>), would contain
a Report with following Parameter names:</p>
<pre><code>WiFi_AP_Assoc.1.10.BytesSent
WiFi_AP_Assoc.1.10.BytesReceived
WiFi_AP_Assoc.1.10.PacketsSent
WiFi_AP_Assoc.1.10.PacketsReceived
WiFi_AP_Assoc.1.10.ErrorsSent
WiFi_AP_Assoc.1.10.RetransCount
WiFi_AP_Assoc.1.10.FailedRetransCount
WiFi_AP_Assoc.1.10.RetryCount
WiFi_AP_Assoc.1.10.MultipleRetryCount
WiFi_AP_Assoc.1.11.BytesSent
WiFi_AP_Assoc.1.11.BytesReceived
WiFi_AP_Assoc.1.11.PacketsSent
WiFi_AP_Assoc.1.11.PacketsReceived
WiFi_AP_Assoc.1.11.ErrorsSent
WiFi_AP_Assoc.1.11.RetransCount
WiFi_AP_Assoc.1.11.FailedRetransCount
WiFi_AP_Assoc.1.11.RetryCount
WiFi_AP_Assoc.1.11.MultipleRetryCount</code></pre>
<p><strong><span id="r-bulk.10a"
class="auto-hoverlink">R-BULK.10a</span></strong> - When the value of
the Exclude Parameter is True, the Parameter Path of the Reference
Parameter MUST be excluded from the Report.</p>
<p>For example, for a device to report all the objects and parameters of
a Wi-Fi Data Elements device and all sub objects and their parameters
EXCEPT the MultiAPDevice object, the following would be configured:</p>
<pre><code>.BulkData.Profile.1.Parameter.1.Name = &quot;DE Device&quot;
.BulkData.Profile.1.Parameter.1.Reference = &quot;Device.WiFi.DataElements.Network.Device.&quot;

.BulkData.Profile.1.Parameter.2.Name = &quot;Remove MultiapDevice&quot;
.BulkData.Profile.1.Parameter.2.Reference = &quot;Device.WiFi.DataElements.Network.Device.*.MultiAPDevice.&quot;
.BulkData.Profile.1.Parameter.2.Exclude = True</code></pre>
<h2 class="annex2 auto-hoverlink" data-info="header"
id="sec:encoding-of-bulk-data">A.7 Encoding of Bulk Data</h2>
<h3 class="annex3 auto-hoverlink" data-info="header"
id="sec:encoding-of-csv-bulk-data">A.7.1 Encoding of CSV Bulk Data</h3>
<p><strong><span id="r-bulk.11"
class="auto-hoverlink">R-BULK.11</span></strong> - CSV Bulk Data SHOULD
be encoded as per RFC 4180 <span class="citation"
data-cites="RFC4180"><a href="#ref-RFC4180"
role="doc-biblioref">[32]</a></span>, MUST contain a header line (column
headers), and the media type MUST indicate the presence of the header
line.</p>
<p>For example:
<code>Content-Type: text/csv; charset=UTF-8; header=present</code></p>
<p>In addition, the characters used to separate fields and rows as well
as identify the escape character can be configured from the characters
used in RFC 4180 <span class="citation" data-cites="RFC4180"><a
href="#ref-RFC4180" role="doc-biblioref">[32]</a></span>.</p>
<p>Using the HTTP example above, the following configures the Agent to
transfer data to the Bulk Data Collector using CSV encoding, separating
the fields with a comma and the rows with a new line character, by
setting the following Parameters:</p>
<pre><code>.BulkData.Profile.1.EncodingType =  &quot;CSV&quot;
.BulkData.Profile.1 CSVEncoding.FieldSeparator = &quot;,&quot;
.BulkData.Profile.1.CSVEncoding.RowSeparator=&quot;&amp;#13;&amp;#10;&quot;
.BulkData.Profile.1.CSVEncoding.EscapeCharacter=&quot;&amp;quot;&quot;</code></pre>
<h4 class="annex4 auto-hoverlink" data-info="header"
id="sec:defining-the-report-layout-of-the-encoded-bulk-data">A.7.1.1
Defining the Report Layout of the Encoded Bulk Data</h4>
<p>The layout of the data in the reports associated with the profiles
allows Parameters to be formatted either as part of a column
(<code>ParameterPerColumn</code>) or as a distinct row
(<code>ParameterPerRow</code>) as defined below. In addition, the report
layout allows rows of data to be inserted with a timestamp stating when
the data is collected.</p>
<p>Using the HTTP example above, the following configures the Agent to
format the data using a Parameter as a row and inserting a timestamp as
the first column entry in each row using the “Unix-Epoch” time. The
information is configured by setting the following Parameters:</p>
<pre><code>.BulkData.Profile.1.CSVEncoding.ReportFormat =&quot;ParameterPerRow&quot;
.BulkData.Profile.1.CSVEncoding.RowTimestamp =&quot;Unix-Epoch&quot;</code></pre>
<p><strong><span id="r-bulk.12"
class="auto-hoverlink">R-BULK.12</span></strong> - The report format of
“<code>ParameterPerRow</code>” MUST format each Parameter using the
<code>ParameterName</code>, <code>ParameterValue</code> and
<code>ParameterType</code> in that order.</p>
<p><strong><span id="r-bulk.13"
class="auto-hoverlink">R-BULK.13</span></strong> - The
<code>ParameterType</code> MUST be the Parameter’s base data type as
described in TR-106 <span class="citation" data-cites="TR-106"><a
href="#ref-TR-106" role="doc-biblioref">[2]</a></span>.</p>
<h4 class="annex4 auto-hoverlink" data-info="header"
id="sec:layout-of-content-for-failed-report-transmissions">A.7.1.2
Layout of Content for Failed Report Transmissions</h4>
<p><em>Note: This is only relevant for the HTTP variant of Bulk Data
Collection.</em></p>
<p>When the value of the <code>NumberOfRetainedFailedReports</code>
Parameter of the <code>BulkData.Profile</code> Object Instance is
<code>-1</code> or greater than <code>0</code>, then the report of the
current reporting interval is appended to the failed reports. For CSV
Encoded data the content of new reporting interval is added onto the
existing content without any header data.</p>
<h4 class="annex4 auto-hoverlink" data-info="header"
id="sec:csv-encoded-report-examples">A.7.1.3 CSV Encoded Report
Examples</h4>
<h5 class="annex5 auto-hoverlink" data-info="header"
id="sec:csv-encoded-reporting-using-parameterperrow-report-format">A.7.1.3.1
CSV Encoded Reporting Using ParameterPerRow Report Format</h5>
<p>Using the configuration examples provided in the previous sections
the configuration for a CSV encoded HTTP report using the
<code>ParameterPerRow</code> report format:</p>
<pre><code>.BulkData.Profile.1
.BulkData.Profile.1.Enable=true
.BulkData.Profile.1.Protocol = &quot;HTTP&quot;
.BulkData.Profile.1.ReportingInterval = 300
.BulkData.Profile.1.TimeReference = &quot;0001-01-01T00:00:00Z&quot;
.BulkData.Profile.1.HTTP.URL =  &quot;https://bdc.acme.com/somedirectory&quot;
.BulkData.Profile.1.HTTP.Username = &quot;username&quot;
.BulkData.Profile.1.HTTP.Password = &quot;password&quot;
.BulkData.Profile.1.HTTP.Compression = &quot;Disabled&quot;
.BulkData.Profile.1.HTTP.Method = &quot;POST&quot;
.BulkData.Profile.1.HTTP.UseDateHeader = true
.BulkData.Profile.1.EncodingType =  &quot;CSV&quot;
.BulkData.Profile.1 CSVEncoding.FieldSeparator = &quot;,&quot;
.BulkData.Profile.1.CSVEncoding.RowSeparator=&quot;&amp;#13;&amp;#10;&quot;
.BulkData.Profile.1.CSVEncoding.EscapeCharacter=&quot;&amp;quot;&quot;
.BulkData.Profile.1.CSVEncoding.ReportFormat =&quot;ParameterPerRow&quot;
.BulkData.Profile.1.CSVEncoding.ReportTimestamp =&quot;Unix-Epoch&quot;
.BulkData.Profile.1.Parameter.1.Name =  &quot;&quot;
.BulkData.Profile.1.Parameter.1.Reference =  &quot;Device.MoCA.Interface.1.Stats.BroadPktSent&quot;
.BulkData.Profile.1.Parameter.2.Name =  &quot;&quot;
.BulkData.Profile.1.Parameter.2.Reference =  &quot;Device.MoCA.Interface.1.Stats.BytesReceived&quot;
.BulkData.Profile.1.Parameter.3.Name =  &quot;&quot;
.BulkData.Profile.1.Parameter.3.Reference =  &quot;Device.MoCA.Interface.1.Stats.BytesSent&quot;
.BulkData.Profile.1.Parameter.4.Name =  &quot;&quot;
.BulkData.Profile.1.Parameter.4.Reference =  &quot;Device.MoCA.Interface.1.Stats.MultiPktReceived&quot;</code></pre>
<p>The resulting CSV encoded data would look like:</p>
<pre><code>ReportTimestamp,ParameterName,ParameterValue,ParameterType
1364529149,Device.MoCA.Interface.1.Stats.BroadPktSent,25248,unsignedLong
1364529149,Device.MoCA.Interface.1.Stats.BytesReceived,200543250,unsignedLong
1364529149, Device.MoCA.Interface.1.Stats.Stats.BytesSent,7682161,unsignedLong
1364529149,Device.MoCA.Interface.1.Stats.MultiPktReceived,890682272,unsignedLong</code></pre>
<h5 class="annex5 auto-hoverlink" data-info="header"
id="sec:csv-encoded-reporting-using-parameterpercolumn-report-format">A.7.1.3.2
CSV Encoded Reporting Using ParameterPerColumn Report Format</h5>
<p>Using the configuration examples provided in the previous sections
the configuration for a CSV encoded HTTP report using the
<code>ParameterPerColumn</code> report format:</p>
<pre><code>.BulkData.Profile.1
.BulkData.Profile.1.Enable=true
.BulkData.Profile.1.Protocol = &quot;HTTP&quot;
.BulkData.Profile.1.ReportingInterval = 300
.BulkData.Profile.1.TimeReference = &quot;0001-01-01T00:00:00Z&quot;
.BulkData.Profile.1.HTTP.URL =  &quot;https://bdc.acme.com/somedirectory&quot;
.BulkData.Profile.1.HTTP.Username = &quot;username&quot;
.BulkData.Profile.1.HTTP.Password = &quot;password&quot;
.BulkData.Profile.1.HTTP.Compression = &quot;Disabled&quot;
.BulkData.Profile.1.HTTP.Method = &quot;POST&quot;
.BulkData.Profile.1.HTTP.UseDateHeader = true
.BulkData.Profile.1.EncodingType =  &quot;CSV&quot;
.BulkData.Profile.1 CSVEncoding.FieldSeparator = &quot;,&quot;
.BulkData.Profile.1.CSVEncoding.RowSeparator=&quot;&amp;#13;&amp;#10;&quot;
.BulkData.Profile.1.CSVEncoding.EscapeCharacter=&quot;&amp;quot;&quot;
.BulkData.Profile.1.CSVEncoding.ReportFormat =&quot;ParameterPerColumn&quot;
.BulkData.Profile.1.CSVEncoding.ReportTimestamp =&quot;Unix-Epoch&quot;
.BulkData.Profile.1.Parameter.1.Name =  &quot;BroadPktSent&quot;
.BulkData.Profile.1.Parameter.1.Reference =  &quot;Device.MoCA.Interface.1.Stats.BroadPktSent&quot;
.BulkData.Profile.1.Parameter.2.Name =  &quot;BytesReceived&quot;
.BulkData.Profile.1.Parameter.2.Reference =  &quot;Device.MoCA.Interface.1.Stats.BytesReceived&quot;
.BulkData.Profile.1.Parameter.3.Name =  &quot;BytesSent&quot;
.BulkData.Profile.1.Parameter.3.Reference =  &quot;Device.MoCA.Interface.1.Stats.BytesSent&quot;
.BulkData.Profile.1.Parameter.4.Name =  &quot;MultiPktReceived&quot;
.BulkData.Profile.1.Parameter.4.Reference =  &quot;Device.MoCA.Interface.1.Stats.MultiPktReceived&quot;</code></pre>
<p>The resulting CSV encoded data with transmission of the last 3
reports failed to complete would look like:</p>
<pre><code>ReportTimestamp,BroadPktSent,BytesReceived,BytesSent,MultiPktReceived
1364529149,25248,200543250,7682161,890682272
1464639150,25249,200553250,7683161,900683272
1564749151,25255,200559350,7684133,910682272
1664859152,25252,200653267,7685167,9705982277</code></pre>
<h3 class="annex3 auto-hoverlink" data-info="header"
id="sec:encoding-of-json-bulk-data">A.7.2 Encoding of JSON Bulk
Data</h3>
<p>Using the HTTP example above, the Set Message is used to configure
the Agent to transfer data to the Bulk Data Collector using JSON
encoding as follows:</p>
<pre><code>.BulkData.Profile.1.EncodingType =  &quot;JSON&quot;</code></pre>
<h4 class="annex4 auto-hoverlink" data-info="header"
id="sec:defining-the-report-layout-of-the-encoded-bulk-data-1">A.7.2.1
Defining the Report Layout of the Encoded Bulk Data</h4>
<p>Reports that are encoded with JSON Bulk Data are able to utilize
different report format(s) defined by the <code>JSONEncoding</code>
object’s <code>ReportFormat</code> Parameter as defined below.</p>
<p>In addition, a “<code>CollectionTime</code>” JSON object can be
inserted into the report instance that defines when the data for the
report was collected.</p>
<p>The following configures the Agent to encode the data using a
Parameter as JSON Object named “<code>CollectionTime</code>” using the
“Unix-Epoch” time format:</p>
<pre><code>.BulkData.Profile.1.JSONEncoding.ReportTimestamp =&quot;Unix-Epoch&quot;</code></pre>
<p>Note: The encoding format of “<code>CollectionTime</code>” is defined
as an JSON Object parameter encoded as:
<code>"CollectionTime":1364529149</code></p>
<p>Reports are defined as an Array of Report instances encoded as:</p>
<pre><code>&quot;Report&quot;:[{...},{...}]</code></pre>
<p><em>Note: Multiple instances of Report instances may exist when
previous reports have failed to be transmitted.</em></p>
<h4 class="annex4 auto-hoverlink" data-info="header"
id="sec:layout-of-content-for-failed-report-transmissions-1">A.7.2.2
Layout of Content for Failed Report Transmissions</h4>
<p><em>Note: This is only relevant for the HTTP variant of Bulk Data
Collection.</em></p>
<p>When the value of the <code>NumberOfRetainedFailedReports</code>
Parameter of the <code>BulkData.Profile</code> Object Instance is
<code>-1</code> or greater than <code>0</code>, then the report of the
current reporting interval is appended to the failed reports. For JSON
Encoded data the report for the current reporting interval is added onto
the existing appended as a new “Data” object array instance as shown
below:</p>
<pre><code>&quot;Report&quot;: [
{Report from a failed reporting interval},
{Report from the current reporting interval}
]</code></pre>
<h4 class="annex4 auto-hoverlink" data-info="header"
id="sec:using-the-objecthierarchy-report-format">A.7.2.3 Using the
ObjectHierarchy Report Format</h4>
<p>When a BulkData profile utilizes the JSON encoding type and has a
<code>JSONEncoding.ReportFormat</code> Parameter value of
“<code>ObjectHierarchy</code>”, then the JSON objects are encoded such
that each Object in the Object hierarchy of the data model is encoded as
a corresponding hierarchy of JSON Objects with the parameters (i.e.,
parameterName, parameterValue) of the object specified as name/value
pairs of the JSON Object.</p>
<p>For example the translation for the leaf Object
“<code>Device.MoCA.Interface.*.Stats.</code>” would be:</p>
<pre><code>    {
        &quot;Report&quot;: [
            {
                &quot;Device&quot;: {
                    &quot;MoCA&quot;: {
                        &quot;Interface&quot;: {
                            &quot;1&quot;: {
                                &quot;Stats&quot;: {
                                    &quot;BroadPktSent&quot;: 25248,
                                    &quot;BytesReceived&quot;: 200543250,
                                    &quot;BytesSent&quot;: 25248,
                                    &quot;MultiPktReceived&quot;: 200543250
                                }
                            },
                            &quot;2&quot;: {
                                &quot;Stats&quot;: {
                                    &quot;BroadPktSent&quot;: 93247,
                                    &quot;BytesReceived&quot;: 900543250,
                                    &quot;BytesSent&quot;: 93247,
                                    &quot;MultiPktReceived&quot;: 900543250
                                }
                            }
                        }
                    }
                }
            }
        ]
    }</code></pre>
<p><em>Note: The translated JSON Object name does not contain the
trailing period “.” of the leaf Object.</em></p>
<h4 class="annex4 auto-hoverlink" data-info="header"
id="sec:using-the-namevaluepair-report-format">A.7.2.4 Using the
NameValuePair Report Format</h4>
<p>When a BulkData profile utilizes the JSON encoding type and has a
<code>JSONEncoding.ReportFormat</code> Parameter value of
“<code>NameValuePair</code>”, then the JSON objects are encoded such
that each Parameter of the data model is encoded as an array instance
with the parameterName representing JSON name token and parameterValue
as the JSON value token.</p>
<p>For example the translation for the leaf Object
“<code>Device.MoCA.Interface.*.Stats.</code>” would be:</p>
<pre><code>{
    &quot;Report&quot;: [
        {
            &quot;Device.MoCA.Interface.1.Stats.BroadPktSent&quot;: 25248,
            &quot;Device.MoCA.Interface.1.Stats.BytesReceived&quot;: 200543250,
            &quot;Device.MoCA.Interface.1.Stats.BytesSent&quot;: 25248,
            &quot;Device.MoCA.Interface.1.Stats.MultiPktReceived&quot;: 200543250,
            &quot;Device.MoCA.Interface.2.Stats.BroadPktSent&quot;: 93247,
            &quot;Device.MoCA.Interface.2.Stats.BytesReceived&quot;: 900543250,
            &quot;Device.MoCA.Interface.2.Stats.BytesSent&quot;: 93247,
            &quot;Device.MoCA.Interface.2.Stats.MultiPktReceived&quot;: 900543250
        }
    ]
}</code></pre>
<p><em>Note: The translated JSON Object name does not contain the
trailing period “.” of the leaf Object.</em></p>
<h4 class="annex4 auto-hoverlink" data-info="header"
id="sec:translating-data-types">A.7.2.5 Translating Data Types</h4>
<p>JSON has a number of basic data types that are translated from the
base data types defined in TR-106 <span class="citation"
data-cites="TR-106"><a href="#ref-TR-106"
role="doc-biblioref">[2]</a></span>. The encoding of JSON Data Types
MUST adhere to RFC 7159 <span class="citation" data-cites="RFC7159"><a
href="#ref-RFC7159" role="doc-biblioref">[35]</a></span>.</p>
<p>TR-106 named data types are translated into the underlying base
TR-106 data types. Lists based on TR-106 base data types utilize the
JSON String data type.</p>
<table>
<thead>
<tr class="header">
<th style="text-align: right;">TR-106 Data Type</th>
<th style="text-align: left;">JSON Data Type</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: right;">base64</td>
<td style="text-align: left;">String: base64 representation of the
binary data.</td>
</tr>
<tr class="even">
<td style="text-align: right;">boolean</td>
<td style="text-align: left;">Boolean</td>
</tr>
<tr class="odd">
<td style="text-align: right;">dateTime</td>
<td style="text-align: left;">String represented as an ISO-8601
timestamp.</td>
</tr>
<tr class="even">
<td style="text-align: right;">hexBinary</td>
<td style="text-align: left;">String: hex representation of the binary
data.</td>
</tr>
<tr class="odd">
<td style="text-align: right;">int, long, unsignedInt, unsignedLong</td>
<td style="text-align: left;">Number</td>
</tr>
<tr class="even">
<td style="text-align: right;">string</td>
<td style="text-align: left;">String</td>
</tr>
</tbody>
</table>
<h4 class="annex4 auto-hoverlink" data-info="header"
id="sec:json-encoded-report-example">A.7.2.6 JSON Encoded Report
Example</h4>
<p>Using the configuration examples provided in the previous sections
the configuration for a JSON encoded HTTP report:</p>
<pre><code>.BulkData.Profile.1
.BulkData.Profile.1.Enable=true
.BulkData.Profile.1.Protocol = &quot;HTTP&quot;
.BulkData.Profile.1.ReportingInterval = 300
.BulkData.Profile.1.TimeReference = &quot;0001-01-01T00:00:00Z&quot;
.BulkData.Profile.1.HTTP.URL =  &quot;https://bdc.acme.com/somedirectory&quot;
.BulkData.Profile.1.HTTP.Username = &quot;username&quot;
.BulkData.Profile.1.HTTP.Password = &quot;password&quot;
.BulkData.Profile.1.HTTP.Compression = &quot;Disabled&quot;
.BulkData.Profile.1.HTTP.Method = &quot;POST&quot;
.BulkData.Profile.1.HTTP.UseDateHeader = true
.BulkData.Profile.1.EncodingType =  &quot;JSON&quot;
.BulkData.Profile.1.JSONEncoding.ReportFormat =&quot;ObjectHierarchy&quot;
.BulkData.Profile.1.JSONEncoding.ReportTimestamp =&quot;Unix-Epoch&quot;
.BulkData.Profile.1.Parameter.1.Reference =  &quot;Device.MoCA.Interface.*.Stats.&quot;</code></pre>
<p>The resulting JSON encoded data would look like:</p>
<pre><code>{
    &quot;Report&quot;: [
        {
            &quot;CollectionTime&quot;: 1364529149,
            &quot;Device&quot;: {
                &quot;MoCA&quot;: {
                    &quot;Interface&quot;: {
                        &quot;1&quot;: {
                            &quot;Stats&quot;: {
                                &quot;BroadPktSent&quot;: 25248,
                                &quot;BytesReceived&quot;: 200543250,
                                &quot;BytesSent&quot;: 25248,
                                &quot;MultiPktReceived&quot;: 200543250
                            }
                        },
                        &quot;2&quot;: {
                            &quot;Stats&quot;: {
                                &quot;BroadPktSent&quot;: 93247,
                                &quot;BytesReceived&quot;: 900543250,
                                &quot;BytesSent&quot;: 93247,
                                &quot;MultiPktReceived&quot;: 900543250
                            }
                        }
                    }
                }
            }
        }
    ]
}</code></pre>
<p>If the value of the
<code>.BulkData.Profile.1.JSONEncoding.ReportFormat</code> Parameter was
“<code>NameValuePair</code>”, the results of the configuration would
be:</p>
<pre><code>{
    &quot;Report&quot;: [
        {
            &quot;CollectionTime&quot;: 1364529149,
            &quot;Device.MoCA.Interface.1.Stats.BroadPktSent&quot;: 25248,
            &quot;Device.MoCA.Interface.1.Stats.BytesReceived&quot;: 200543250,
            &quot;Device.MoCA.Interface.1.Stats.BytesSent&quot;: 25248,
            &quot;Device.MoCA.Interface.1.Stats.MultiPktReceived&quot;: 200543250,
            &quot;Device.MoCA.Interface.2.Stats.BroadPktSent&quot;: 93247,
            &quot;Device.MoCA.Interface.2.Stats.BytesReceived&quot;: 900543250,
            &quot;Device.MoCA.Interface.2.Stats.BytesSent&quot;: 93247,
            &quot;Device.MoCA.Interface.2.Stats.MultiPktReceived&quot;: 900543250
        }
    ]
}</code></pre>
<h1 class="appendix1 auto-hoverlink" data-info="header"
id="sec:software-module-management">Appendix I: Software Module
Management</h1>
<p>This section discusses the Theory of Operation for Software Module
Management using USP and the Software Module Object defined in the Root
data model.</p>
<p>As the home networking market matures, devices in the home are
becoming more sophisticated and more complex. One trend in enhanced
device functionality is the move towards more standardized platforms and
execution environments (such as Java, Linux, OSGi, Docker, etc.).
Devices implementing these more robust platforms are often capable of
downloading new applications dynamically, perhaps even from third-party
software providers. These new applications might enhance the existing
capabilities of the device or enable the offering of new services.</p>
<p>This model differs from previous device software architectures that
assumed one monolithic firmware that was downloaded and applied to the
device in one action.</p>
<p>That sophistication is a double-edged sword for developers,
application providers, and service providers. On one hand, these devices
are able to offer new services to customers and therefore increase the
revenue per customer, help companies differentiate, and reduce churn
with “sticky” applications that maintain interest. On the other hand,
the increased complexity creates more opportunities for problems,
especially as the users of these home-networking services cease to be
early adopters and move into the mainstream. It is important that the
increased revenue opportunity is not offset with growing activation and
support costs.</p>
<p>In order to address the need of providing more compelling dynamic
applications on the device while ensuring a smooth “plug and play” user
experience, it is necessary for manufacturers, application providers,
and service providers to make use of USP to remotely manage the life
cycle of these applications, including install, activation,
configuration, upgrade, and removal. Doing so ensures a positive user
experience, improves service time-to-market, and reduces operational
costs related with provisioning, support, and maintenance.</p>
<h2 class="appendix2 auto-hoverlink" data-info="header"
id="sec:lifecycle-management">I.1 Lifecycle Management</h2>
<p>There are a number of possible actions in managing the lifecycle of
these dynamic applications. One might want to install a new application
on the device for the user. One might want to update existing
applications when new versions or patches are available. One might want
to start and/or stop these applications as well. Finally, it may be
necessary to uninstall applications that are no longer needed (or
perhaps paid for) by the user.</p>
<p>The specifics of how applications run in different environments vary
from platform to platform. In order to avoid lifecycle management
tailored to each specific operating environment, USP-based software
management defines abstract state models and abstract software module
concepts as described in the following sections. These concepts are not
tied to any particular platform and enable USP to manage dynamic
software on a wide range of devices in a wide range of environments.</p>
<h2 class="appendix2 auto-hoverlink" data-info="header"
id="sec:software-modules">I.2 Software Modules</h2>
<p>A Software Module is any software entity that will be installed on a
device. This includes modules that can be installed/uninstalled and
those that can be started and stopped. All software on the device is
considered a software module, with the exception of the primary
firmware, which plays a different enough role that it is considered a
separate entity.</p>
<p>A software module exists on an Execution Environment (EE), which is a
software platform that supports the dynamic loading and unloading of
modules. It might also enable the dynamic sharing of resources among
entities, but this differs across various execution environments.
Typical examples include Linux, Docker, OSGi, .NET, Android, and Java
ME. It is also likely that these environments could be “layered,” i.e.,
that there could be one primary environment such as Linux on which one
or more OSGi frameworks are stacked. This is an implementation specific
decision, however, and USP-based module management does not attempt to
enable management of this layering beyond exposing which EE a given
environment is layered on top of (if any). USP-based Software Module
Management also does not attempt to address the management of the
primary firmware image, which is expected to be managed via the device’s
Firmware Image Objects defined in the Root data model.</p>
<p>Software modules come in two types: Deployment Units (DUs) and
Execution Units (EUs). A DU is an entity that can be deployed on the EE.
It can consist of resources such as functional EUs, configuration files,
or other resources. Fundamentally it is an entity that can be Installed,
Updated, or Uninstalled. Each DU can contain zero or more EUs but the
EUs contained within that DU cannot span across EEs. An EU is an entity
deployed by a DU, such as services, scripts, software components, or
libraries. The EU initiates processes to perform tasks or provide
services. Fundamentally it is an entity that can be Started or Stopped.
EUs also expose configuration for the services implemented, either via
standard Software Module Management related data model Objects and
Parameters or via EU specific Objects and Parameters.</p>
<p>It is possible that Software Modules can have dependencies on each
other. For example a DU could contain an EU that another DU depends on
for functioning. If all the resources on which a DU depends are present
and available on an EE, it is said to be Resolved. Otherwise the EUs
associated with that DU might not be able to function as designed. It is
outside the scope of Software Module Management to expose these
dependencies outside of indicating whether a particular DU is RESOLVED
or not.</p>
<h3 class="appendix3 auto-hoverlink" data-info="header"
id="sec:deployment-units">I.2.1 Deployment Units</h3>
<p>Below is the state machine diagram<a href="#fn1" class="footnote-ref"
id="fnref1" role="doc-noteref"><sup>1</sup></a> for the lifecycle of
DUs.</p>
<figure id="fig:deployment-unit-state-diagram">
<img src="extensions/software-module-management/du_state.png"
id="img:deployment-unit-state-diagram"
alt="Deployment Unit State Diagram" />
<figcaption><div class="auto-hoverlink"
data-anchor="fig:deployment-unit-state-diagram">
Figure 26: Deployment Unit State Diagram
</div></figcaption>
</figure>
<p>This state machine shows 5 individual states (3 of which are
transitory) and 3 explicitly triggered state transitions.</p>
<p>The explicit transitions among the non-transitory states are
triggered by the USP commands: <code>InstallDU()</code>,
<code>Update()</code> and <code>Uninstall()</code> or triggered via
means other than the USP commands (e.g. user-triggered or
device-triggered).</p>
<p>The explicit transitions include:</p>
<p>1 - Install, which initiates the process of Installing a DU. The
device might need to transfer a file from the location indicated by a
URL in the method call. Once the resources are available on the device,
the device begins the installation process:</p>
<ul>
<li><p>In the Installing state, the DU is in the process of being
Installed and will transition to that state unless prevented by a fault.
Note that the Controller has the option to choose which EE to install a
particular DU to, although it can also leave that choice up to the
device. If the Controller does specify the EE, it is up to the
Controller to specify one that is compatible with the DU it is
attempting to Install (e.g., an OSGi framework for an OSGi
bundle).</p></li>
<li><p>In the Installed state, the DU has been successfully downloaded
and installed on the relevant EE. At this point it might or might not be
Resolved. If it is Resolved, the associated EUs can be started;
otherwise an attempt to start the associated EUs will result in a
failure. How dependencies are resolved is implementation and EE
dependent.</p></li>
</ul>
<p><strong><span id="r-smm.0"
class="auto-hoverlink">R-SMM.0</span></strong> - An installed DU MUST
persist across reboots. The DU persists until it is Uninstalled.</p>
<p>2 - Update, which initiates a process to update a previously existing
DU. As with Install, the device might need to transfer a file from the
location indicated by a URL in the respective command. If no URL is
provided in the command, the device uses the last URL stored in the
<code>DeploymentUnit</code> table (including any related authentication
credentials) used from either Install or a previous Update. Once the
resources are available on the device, the device begins the updating
process:</p>
<ul>
<li><p>In the Updating state, the DU is in the process of being Updated
and will transition to the Installed state. As with initial
installation, the DU might or might not have dependencies resolved at
this time.</p></li>
<li><p>During the Updating state, the associated EUs that had been in
the Active state transition to Idle during the duration of the Update.
They are automatically restarted once the Update process is
complete.</p></li>
</ul>
<p>3 - Uninstall, which initiates the process of uninstalling the DU and
removing the resources from the device. It is possible that a DU to be
Uninstalled could have been providing shared dependencies to another DU;
it is possible therefore that the state of other DUs and/or EUs could be
affected by the DU being Uninstalled.</p>
<ul>
<li><p>In the Uninstalling state, the DU is in the process of being
Uninstalled and will transition to that state unless prevented by a
fault.</p></li>
<li><p>In the Uninstalled state, the DU is no longer available as a
resource on the device. Garbage clean up of the actual resources are EE
and implementation dependent. In many cases, the resource(s) will be
removed automatically at the time of un-installation. The removal of any
associated EUs is part of DU clean up.</p></li>
</ul>
<p><strong><span id="r-smm.1"
class="auto-hoverlink">R-SMM.1</span></strong> - The device MUST
complete the requested operation within 24 hours of responding to the
<code>InstallDU()</code>, <code>Update()</code> or
<code>Uninstall()</code> command. If the device has not been able to
complete the operation request within that 24 hour time window, it MUST
consider the operation in error and send the appropriate Error Message
to the operation in the <code>DUStateChange!</code> event. If a DU state
change fails, the device MUST NOT attempt to retry the state change on
its own initiative, but instead MUST report the failure of the command
in the <code>DUStateChange!</code> event.</p>
<p>The inventory of available DUs along with their current state can be
found in the <code>SoftwareModules</code> service element found in the
Root data model, i.e., the
<code>SoftwareModules.DeploymentUnit.{i}.</code> Object. This Object
contains a list of all the DUs currently on the device, along with
pertinent information such as DU identifiers, current state, whether the
DU is Resolved, information about the DU itself such as vendor and
version, the list of associated EUs, and the EEs on which the particular
DU is installed.</p>
<p>DUs have a number of identifiers, each contributed by a different
actor in the ecosystem:</p>
<ul>
<li><p>A Universally Unique Identifier (UUID) either assigned by the
Controller or generated by the device at the time of Installation. This
identifier gives the management server a means to uniquely identify a
particular DU across the population of devices on which it is installed.
A DU will, therefore, have the same UUID on different devices, but there
can be no more than one DU with the same UUID and version installed to
an EE on a particular device. See <a href="#sec:uuid-generation"
class="heading">UUID Generation</a> below for more information.</p></li>
<li><p>A Deployment Unit Identifier (DUID) assigned by the EE on which
it is deployed; this identifier is specific to the particular EE, and
different EEs might have different logic for the assigning of this
value. A Name assigned by the author of the DU.</p></li>
</ul>
<p>The creation of a particular DU instance in the data model occurs
during the Installation process. It is at this time that the DUID is
assigned by the EE. Upon Uninstall, the data model instance will be
removed from the DU table once the resource itself has been removed from
the device. Since garbage clean up is EE and implementation dependent,
it is therefore possible that a particular DU might never appear in the
data model in the Uninstalled state but rather disappear at the time of
the state transition. It is also possible that an event, such as a
reboot, could be necessary before the associated resources are
removed.</p>
<h4 class="appendix4 auto-hoverlink" data-info="header"
id="sec:uuid-generation">I.2.1.1 UUID Generation</h4>
<p>An important aspect of the UUID is that it might be generated by
either the Controller and provided to the device as part of the Install
command, or generated by the device either if the Controller does not
provide a UUID in the Install command or if the DU is Installed outside
USP-based management, such as at the factory or via a LAN-side mechanism
(e.g. UPnP DM). Because the UUID is meant to uniquely identify a DU
across a population of devices, it is important that the UUID be the
same whether generated by the Controller or the device. In order to
ensure this, the UUID is generated (whether by Controller or device)
according to the rules defined by RFC 4122 <span class="citation"
data-cites="RFC4122"><a href="#ref-RFC4122"
role="doc-biblioref">[31]</a></span> Version 5 (Name-Based) and the
Device:2 Data Model <span class="citation" data-cites="TR-181"><a
href="#ref-TR-181" role="doc-biblioref">[3]</a></span>. The following
are some possible scenarios:</p>
<ul>
<li><p>The DU is Installed via USP with a Controller generated UUID and
is subsequently Updated/Uninstalled via USP. All post-Install management
actions require the UUID to address the DU, which is retained across
version changes.</p></li>
<li><p>The DU is factory Installed with a device generated UUID and is
subsequently Updated/Uninstalled via USP. In this case the Controller
can either choose to generate this UUID if it has access to the
information necessary to create it or to learn the UUID by interrogating
the data model.</p></li>
<li><p>The DU is Installed via USP with a Controller generated UUID and
is subsequently Updated/Uninstalled via a LAN-side mechanism. In this
scenario it is possible that the LAN-side mechanism is unaware of the
UUID and uses its own protocol-specific mechanism to identify and
address the DU. The UUID, however, is still retained across version
changes. If <code>DUStateChange!</code> events are subscribed to by the
Controller for the device, the device also sends that event (containing
the UUID) to the subscribed Controllers once the LAN-side triggered
state change has completed.</p></li>
<li><p>The DU is Installed via USP but the Controller provides no UUID
in the <code>InstallDU()</code> command. In this case the device
generates the UUID, which must be used by the Controller in any future
USP-based Updates or Uninstalls. Depending on its implementation, the
Controller might choose to generate the UUID at the time of the future
operations, learn the value of the UUID from the
<code>DUStateChange!</code> event for the <code>InstallDU()</code>,
<code>Update()</code> or <code>Uninstall()</code> command, or learn it
by interrogating the data model.</p></li>
</ul>
<p>The DU is Installed via a LAN-side mechanism and is subsequently
Updated/Uninstalled via USP. Since it is likely that the LAN-side
mechanism does not provide a Version 5 Name-Based UUID in its
protocol-specific Install operation, it is expected that the device
generates the UUID in this case when it creates the DU instance in the
data model. Depending on its implementation, the Controller might choose
to generate the UUID for later operations if it has access to the
information necessary to create it, learn the UUID from the
<code>DUStateChange!</code> event, if subscribed, or learn it by
interrogating the instantiated data model.</p>
<h3 class="appendix3 auto-hoverlink" data-info="header"
id="sec:execution-units">I.2.2 Execution Units</h3>
<p>Below is the state machine diagram<a href="#fn2" class="footnote-ref"
id="fnref2" role="doc-noteref"><sup>2</sup></a> for the lifecycle of
EUs.</p>
<figure id="fig:execution-unit-state-diagram">
<img src="extensions/software-module-management/eu_state.png"
id="img:execution-unit-state-diagram"
alt="Execution Unit State Diagram" />
<figcaption><div class="auto-hoverlink"
data-anchor="fig:execution-unit-state-diagram">
Figure 27: Execution Unit State Diagram
</div></figcaption>
</figure>
<p>This state machine shows 5 states (3 of them transitory) and four
explicitly triggered state transitions.</p>
<p>The state transitions between the non-transitory states are triggered
by executing the
<code>SoftwareModules.ExecutionUnit.{i}.SetRequestedState()</code> or
the <code>SoftwareModules.ExecutionUnit.{i}.Restart()</code> command.
The explicit transitions are as follows:</p>
<ul>
<li><p>In order to Start an EU, the Controller sends a
<code>SetRequestedState()</code> command with the
<code>RequestedState</code> Parameter set to Active. The EU enters the
Starting state, during which it takes any necessary steps to move to the
Active state, and it will transition to that state unless prevented by a
fault. Note that an EU can only be successfully started if the DU with
which it is associated has all dependencies Resolved. If this is not the
case, then the EU’s status remains as Idle, and the
<code>ExecutionFaultCode</code> and <code>ExecutionFaultMessage</code>
Parameters are updated appropriately.</p></li>
<li><p>In order to Stop an EU, the Controller sends a
<code>SetRequestedState()</code> command with the
<code>RequestedState</code> Parameter set to Idle. The EU enters the
Stopping state, during which it takes any necessary steps to move to the
Idle state, and then transitions to that state.</p></li>
<li><p>In order to Restart an EU, the Controller sends a
<code>Restart()</code> command. The EU enters the Restarting state,
during which it stops execution and then re-starts before transitioning
back to the Active state. The command may be rejected with error code
7230 (Invalid Execution Environment State) if the EU is currently in a
state of Stopping.</p></li>
<li><p>It is also possible that the EU could transition to the Active,
Restarting, or Idle state without being explicitly instructed to do so
by a Controller (e.g., if the EU is allowed to AutoStart, in combination
with the run level mechanism, or if an AutoRestart mechanism is enabled,
or if operation of the EU is disrupted because of a later dependency
error). A Controller can be notified of these autonomous state changes
by creating a <code>Subscription.{i}.</code> Object Instance for a
<code>ValueChange</code> notification type that references the
<code>SoftwareModules.ExecutionUnit.{i}.Status</code>
Parameter.</p></li>
</ul>
<p>The inventory of available EUs along with their current state can be
found in the <code>SoftwareModules</code> service element found in the
Root data model; i.e., the
<code>SoftwareModules.ExecutionUnit.{i}.</code> Object. This Object
contains a list of all the EUs currently on the device along with
accompanying status and any current errors as well as resource
utilization related to the EU, including memory and disk space in
use.</p>
<p>EUs have a number of identifiers, each contributed by a different
actor in the ecosystem:</p>
<ul>
<li><p>An Execution Unit Identifier (EUID) assigned by the EE on which
it is deployed; this identifier is specific to the particular EE, and
different EEs might have different logic for assigning this value. There
can be only one EU with a particular EUID.</p></li>
<li><p>A Name provided by the developer and specific to the associated
DU.</p></li>
<li><p>A Label assigned by the EE; this is a locally defined name for
the EU.</p></li>
</ul>
<p>The creation of a particular EU instance in the data model occurs
during the Installation process of the associated DU. It is at this time
that the EUID is assigned by the EE as well. The configuration exposed
by a particular EU is available from the time the EU is created in the
data model, whether or not the EU is Active. Upon Uninstall of the
associated DU, it is expected that the EU would transition to the Idle
State, and the data model instance would be removed from the EU table
once the associated resources had been removed from the device. Garbage
clean up, however, is EE and implementation dependent.</p>
<p>Although the majority of EUs represent resources such as scripts that
can be started or stopped, there are some inert resources, such as
libraries, which are represented as EUs. In this case, these EUs behave
with respect to the management interface as a “regular” EU. In other
words, they respond successfully to Stop and Start commands, even though
they have no operational meaning and update the
<code>SoftwareModules.ExecutionUnit.{i}.Status</code> Parameter
accordingly. In most cases the <code>Status</code> would not be expected
to transition to another state on its own, except in cases where its
associated DU is Updated or Uninstalled or its associated EE is Enabled
or Disabled, in which cases the library EU acts as any other EU.
Restarting such an EU will result in a successful response but the state
remains unchanged.</p>
<p>The EUs created by the Installation of a particular DU might provide
functionality to the device that requires configuration by a Controller.
This configuration could be exposed via the USP data model in five
ways:</p>
<ol type="1">
<li><p>Service data model (if, for example, the EU provides VoIP
functionality, configuration would be exposed via the Voice Service data
model defined in TR-104).</p></li>
<li><p>Standard Objects and parameters in the device’s root data model
(if, for example, the EU provides port mapping capability, the
configuration would be exposed via the port mapping table defined in the
Device:2 Data Model <span class="citation" data-cites="TR-181"><a
href="#ref-TR-181" role="doc-biblioref">[3]</a></span>).</p></li>
<li><p>Instances of standard Objects in the Root or any Service data
model, (if, for example, the EU provides support for an additional Codec
in a VoIP service).</p></li>
<li><p>Vendor extension Objects and Parameters that enhance and extend
the capabilities of standard Objects (if, for example, the EU provides
enhanced UserInterface capabilities)</p></li>
<li><p>Standalone vendor extension Objects that are directly controlled
Objects of the EU (for example, a new vendor specific Object providing
configuration for a movies on demand service).</p></li>
</ol>
<p>In all cases the <a href="#sec:the-getsupporteddm-message"
class="heading">GetSupportedDM</a> and <a href="#sec:getinstances"
class="heading">GetInstances</a> Messages can be used to retrieve the
associated supported data model along with the corresponding Object
Instances.</p>
<p>All data model services, Objects, and Parameters related to a
particular EU come into existence at the time of Installation or Update
of the related DU, The related data model disappears from the device’s
data model tree at the time of Uninstall and clean up of the related DU
resources. It is possible that the device could encounter errors during
the process of discovering and creating EUs; if this happens, it is not
expected that the device would roll back any data model it has created
up until this point but would rather set the
<code>ExecutionFaultCode</code> of the EU to “<code>Unstartable</code>.”
In this case, it is not expected that any faults (with the exception of
System Resources Exceeded) would have been generated in response to the
Install or Update operation. See below for more information on EU
faults.</p>
<p>The configuration of EUs could be backed up and restored using vendor
configuration files. The EU Object in the data model contains a
Parameter, which is a path reference to an instance in the vendor config
file table in the Root data model. This path reference indicates the
vendor config file associated with the configuration of the particular
EU from which the associated Object Instance could be backed up or
restored using respective commands for that Object Instance.</p>
<p>It is also possible that applications could have dedicated log files.
The EU Object also contains a Parameter, which is a path reference to an
instance in the log file table in the root data model. This path
reference indicates the log file associated with a particular EU from
which the referenced Object Instance could be retrieved using the Upload
command for that Object Instance.</p>
<h2 class="appendix2 auto-hoverlink" data-info="header"
id="sec:execution-environment-concepts">I.3 Execution Environment
Concepts</h2>
<p>As discussed above, an EE is a software platform that supports the
dynamic loading and unloading of modules. A given device can have
multiple EEs of various types and these EEs can be layered on top of
each other. The following diagram gives a possible implementation of
multiple EEs.</p>
<figure id="fig:multi-exec-env">
<img src="extensions/software-module-management/smm_concepts.png"
id="img:possible-multi-execution-environment-implementation"
alt="Possible Multi-Execution Environment Implementation" />
<figcaption><div class="auto-hoverlink"
data-anchor="fig:multi-exec-env">
Figure 28: Possible Multi-Execution Environment Implementation
</div></figcaption>
</figure>
<p>In this example, the device exposes its Linux Operating System as an
EE and has two different OSGi frameworks layered on top of it, all of
which are modeled as separate ExecEnv Object Instances. In order to
indicate the layering to a Controller, the two OSGi framework Objects
(<code>.ExecEnv.2</code> and <code>.ExecEnv.3</code>) would populate the
<code>Exec.Env.{i}.Parent</code> Parameter with a path reference to the
Linux Object (<code>.ExecEnv.1</code>). The Linux EE Object would
populate that Parameter with an empty string to indicate that it is not
layered on top of any managed EE.</p>
<p><em>Note that the above is merely an example; whether a device
supports multiple frameworks of the same type and whether it exposes its
Operating System as an Execution Environment for the purposes of
management is implementation specific.</em></p>
<p>Multiple versions of a DU can be installed within a single EE
instance, but there can only be one instance of a given version at a
time. In the above diagram, there are two versions of DU1, v1.0 and v1.2
installed on <code>.ExecEnv.2.</code> If an attempt is made to update
DU1 to version 1.2, or to install another DU with version 1.0 or 1.2, on
<code>ExecEnv.2</code>, the operation will fail.</p>
<p>A DU can also be installed to multiple EEs. In the above example, DU1
is installed both to <code>ExecEnv.2</code>and <code>ExecEnv.3</code>.
The Installation is accomplished by sending two separate
<code>InstallDU()</code> commands where one command’s
<code>ExecEnvRef</code> Parameter has a value of
“<code>.ExecEnv.2</code>” and the other command’s
<code>ExecEnvRef</code> Parameter as a value of “.ExecEnv.3” ; note that
the USP Controller is required to handle cases where there is an
expectation that the installation of both deployment units is
atomic.</p>
<p>When DUs are Updated, the DU instances on all EEs are affected. For
example, in the above diagram, if DU1 v.1.0 is updated to version 2.0,
the instances on both <code>.ExecEnv.2</code> and
<code>.ExecEnv.3</code> will update to version 2.0.</p>
<p>For Uninstall, a Controller can either indicate the specific EE from
which the DU should be removed, or not indicate a specific EE, in which
case the DU is removed from all EEs.</p>
<p>An EE can be enabled and disabled by a Controller. Sending a
<code>SoftwareModules.ExecEnv.{i}.Restart()</code> command is equivalent
to first disabling and then later enabling the EE, but also allows the
reason for and the time of the restart to be recorded in
<code>SoftwareModules.ExecEnc.{i}.RestartReason</code> and
<code>SoftwareModules.ExecEnc.{i}.LastRestarted</code> respectively.</p>
<figure id="fig:execution-environment-state-diagram">
<img src="extensions/software-module-management/ee_state.png"
id="img:execution-environment-state-diagram"
alt="Execution Environment State Diagram" />
<figcaption><div class="auto-hoverlink"
data-anchor="fig:execution-environment-state-diagram">
Figure 29: Execution Environment State Diagram
</div></figcaption>
</figure>
<p>When an EE instance is disabled by a Controller, the EE itself shuts
down. Additionally, any EUs associated with the EE automatically
transition to Stopped and the <code>ExecutionFaultCode</code> Parameter
value is <code>Unstartable</code>. The state of the associated DUs
remains the same. If a USP command that changes the DU state is
attempted on any of the DUs associated with a disabled EE, the operation
fails and an “<code>Invalid value</code>” error is returned in the
<code>DUStateChange!</code> event for the affected DU instance. It
should be noted if the Operating System of the device is exposed as an
EE, disabling it could result in the device being put into a
non-operational and non-manageable state. It should also be noted that
disabling the EE on which the USP Agent resides can result in the device
becoming unmanageable via USP.</p>
<h3 class="appendix3 auto-hoverlink" data-info="header"
id="sec:managing-execution-environments">I.3.1 Managing Execution
Environments</h3>
<p>An implementation may provide for Execution Environments to be added
or removed at run-time. These implementations should provide the
<code>SoftwareModules.ExecEnvClass</code> table and its associated
<code>AddExecEnv()</code> command. For example in <a
href="#fig:multi-exec-env" class="figure">Figure 28</a> the
<code>ExecEnvClassRef</code> of the Linux EE would point to one entry in
<code>SoftwareModules.ExecEnvClass</code> while the two OSGI Frameworks
would point to to another entry. A new OSGI Framework instance could be
created using
<code>SoftwareModules.ExecEnvClass.{i}.AddExecEnv()</code>, or an
instance could be removed using
<code>SoftwareModules.ExecEnv.{i}.Remove()</code>.</p>
<p>The <code>ExecEnvClass.{i}.Capability</code> table describes the
class of EE in terms of the kinds of DUs it supports. For example a web
services framework would probably support the installation of WAR files,
but it may also support OSGi Bundles as a DU format.</p>
<p>(Note: In the example shown in <a href="#fig:multi-exec-env"
class="figure">Figure 28</a> the <code>ExecEnvClassRef</code> of the
Linux EE could also be left blank, as apparently this EE does not
support the installation of any kind of DU nor is it possible to add new
instances.)</p>
<h3 class="appendix3 auto-hoverlink" data-info="header"
id="sec:application-data-volumes">I.3.2 Application Data Volumes</h3>
<p>An Execution Environment may offer filesystem storage facilities to
the software modules which are installed into it; these EEs should
provide the <code>SoftwareModules.ExecEnv.{i}.ApplicationData</code>
table which exposes the storage volumes which currently exist.</p>
<p>Each application data volume is associated with an
“<code>application</code>” and a volume Name (so that an application may
own multiple volumes). The application is identified by the UUID of its
DU, and hence by the Vendor and Name of a Deployment Unit. This makes it
possible for a data volume to persist across an Update of the DU or even
across an Uninstall and subsequent re-Install, if desired. At the
opposite extreme, an application data volume may be marked
“<code>Retain Until Stopped</code>”, meaning that the data will be lost
when application no longer has any Active EUs (conceptually these
volumes are destroyed, and will be re-created when an EU becomes
Active).</p>
<p>The set of application data volumes needed by an application are
specified in an optional parameter of the <code>InstallDU()</code>
command, and can be modified by the <code>Update()</code> command. Note
that the parameter specifies the retention policy for each volume, but
not where it is stored - a volume might be stored on the local flash of
one device while another device would store the same volume in the
cloud. This makes it easier to design applications which can be deployed
across a wide range of devices without needing to know the detailed
storage layout of each device.</p>
<p>By default the <code>Update()</code> and <code>Uninstall()</code>
commands cause all application data volumes associated with the affected
DUs to be lost. This can be prevented by setting the optional
<code>RetainData</code> argument to <code>true</code>; in the case of
<code>Uninstall()</code> this will result in an “<code>orphaned</code>”
volume with an <code>ApplicationUUID</code> which does not match any DU
installed in the EE. The
<code>SoftwareModules.ExecEnv.{i}.ApplicationData.{i}.Remove()</code>
command is available to clean up orphaned data volumes if they are no
longer needed. Implementations are advised to reject any attempt to
invoke this command on a data volume with an
<code>ApplicationUUID</code> which matches that of a DU which is
currently installed in the EE, with error code 7229 (Invalid Deployment
Unit State).</p>
<h3 class="appendix3 auto-hoverlink" data-info="header"
id="sec:signing-deployment-units">I.3.3 Signing Deployment Units</h3>
<p>An Execution Environment may require any DU which is Installed into
it to be signed by an authorized principal. A signature may take many
forms, such as a JSON Web Signature (JWS, RFC 7515) or GNU Privacy Guard
(GPG, RFC 4880); however in essence it always amounts to a
cryptographically-signed statement that a certain artifact is authentic.
Typically the document is identified by a hash of its contents (so the
signature also provides assurance of integrity), and asymmetric
encryption is used so that both the signature itself and the public key
which can be used to verify its authenticity can be transmitted over an
insecure channel without risk of compromise.</p>
<p>It may be possible to derive the URL of the signature from the URL of
the DU itself, for example by appending a suffix such as “.sig”.
Alternatively an optional <code>Signature</code> argument can be
included in the <code>Install</code> or <code>Update</code> command,
providing greater operational flexibility.</p>
<p>If the public key(s) which are used to verify signatures are
distributed in the form of X.509 certificates, these may be stored in
the <code>Device.Security.Certificate</code> table. the Execution
Environment may then list the relevant entries in its
<code>Signers</code> parameter.</p>
<h2 class="appendix2 auto-hoverlink" data-info="header"
id="sec:fault-model">I.4 Fault Model</h2>
<p>Faults can occur at a number of steps in the software module process.
The following sections discuss Deployment Unit faults and Execution Unit
faults.</p>
<h3 class="appendix3 auto-hoverlink" data-info="header"
id="sec:du-faults">I.4.1 DU Faults</h3>
<p>There are two basic types of DU faults: Operation failures and USP
message errors that are the result of the invoking the
<code>InstallDU()</code>,<code>Update()</code>,<code>UninstallDU()</code>,
<code>Reset()</code>, <code>SetRunLevel()</code> and
<code>SetRequestedState()</code> commands.</p>
<h4 class="appendix4 auto-hoverlink" data-info="header"
id="sec:install-faults">I.4.1.1 Install Faults</h4>
<p>Most Install faults will be recognized before resources or instances
are created on the device. When there is an Operation failure at
Install, there are no resources installed on the device and no DU (or
EU) instances are created in the data model. Similarly, if there are any
command failures, besides System Resources Exceeded, there are no
resources installed on the device and no DU (or EU) instances created in
the data model.</p>
<p>There are a number of command failures defined for Installation. The
first category is those faults associated with the file server or
attempt to transfer the DU resource and are the same as those defined
for the existing <code>InstallDU()</code> and <code>Update()</code>
commands. These include:</p>
<ul>
<li>Userinfo element being specified in the URL</li>
<li>The URL being unavailable (either because the host cannot be reached
or because the resource is unavailable)</li>
<li>Authentication failures due to incorrectly supplied credentials</li>
<li>The URL transport method specified not being supported by the device
or server</li>
<li>The file transfer being interrupted (because of a device reboot or
loss of connectivity, for example)</li>
</ul>
<p>The second category of faults relate to issues with the DU and the
Execution Environment. These are specific to Software Module Management
and include:</p>
<ul>
<li>The EE reference specified by a Controller in the
<code>InstallDU()</code> command does not exist in the data model. Note
that the Controller can simply omit the EE reference in the request and
allow the deice to choose the destination.</li>
<li>The EE being disabled. This fault can occur when the
<code>InstallDU()</code> command explicitly specifies a disabled EE. If
there is no EE specified in the request, this fault could occur because
the only possible destination EE for the DU (the only OSGi framework
instance in the case of an OSGi bundle, for example) is disabled. The
device is expected to make every attempt not to use a disabled EE in
this scenario, however.</li>
<li>Any mismatch existing between the DU and the EE (attempting to
install a Linux package on an OSGi framework instance, for example).
This fault can occur when the request explicitly specifies a mismatching
EE. If there is no EE specified in the request, this fault could occur
when there is no EE at all on the device that can support the DU.</li>
<li>A DU of the same version already existing on the EE.</li>
</ul>
<p>Finally there are a number of faults related to the DU resource
itself. These include:</p>
<ul>
<li>The UUID in the request not matching the format specified in RFC
4122 <span class="citation" data-cites="RFC4122"><a href="#ref-RFC4122"
role="doc-biblioref">[31]</a></span> Version 5 (Name-based).</li>
<li>A corrupted DU resource, or the DU not being installable for other
reasons, such as not being signed by any trusted entity</li>
<li>The installation of the DU requiring more system resources, such as
disk space, memory, etc., than the device has available. Note that this
error is not to be used to indicate that more operations have been
requested than the device can support, which is indicated by the
Resourced Exceeded error (described above).</li>
</ul>
<h4 class="appendix4 auto-hoverlink" data-info="header"
id="sec:update-faults">I.4.1.2 Update Faults</h4>
<p>When there is a fault on an Update of a DU of any kind, the DU
remains at the version it was before the attempted DU state change, and
it also remains in the Installed state (i.e., it is not Uninstalled). If
for any reason the a Controller wishes to remove a DU after an
unsuccessful Update, it must do so manually using an
<code>Uninstall()</code> command. When there is a USP message error for
the Update, there are no new resources installed on the device and no DU
(or EU) instances are changed in the data model. Similarly, if there are
any Operation failures, besides System Resources Exceeded, there are no
new resources installed on the device and no DU (or EU) instances are
changed in the data model. The state of any associated EUs or any
dependent EUs in the event of an Update failure is EE and implementation
dependent.</p>
<p>There are a number of Operation failures defined for Update of a DU.
The first category is those faults associated with the file server or
attempt to transfer the DU resource and are the same as those defined
for the existing <code>Update()</code> command. These include:</p>
<ul>
<li>Userinfo element being specified in the URL</li>
<li>The URL being unavailable (either because the host cannot be reached
or because the resource is unavailable)</li>
<li>Authentication failures due to incorrectly supplied credentials</li>
<li>The URL transport method specified not being supported by the device
or server</li>
<li>The file transfer being interrupted (because of a device reboot or
loss of connectivity, for example)</li>
</ul>
<p>The second category of faults relate to issues with the DU and the
Execution Environment. These are specific to Software Module Management
and include:</p>
<ul>
<li>The EE on which the targeted DU resides being disabled. This fault
can occur when the request explicitly specifies the UUID of a DU on a
disabled EE or when the request explicitly specifies a URL last used by
a DU on a disabled EE. If neither the URL nor UUID was specified in the
request, this fault can occur when at least one DU resides on a disabled
EE.</li>
<li>Any mismatch existing between the DU and the EE. This fault occurs
when the content of the updated DU does not match the EE on which it
resides (for example, an attempt is made to Update a Linux package with
a DU that is an OSGi bundle).</li>
<li>Updating the DU would cause it to have the same version as a DU
already installed on the EE.</li>
<li>The version of the DU not being specified in the request when there
are multiple versions installed on the EE.</li>
</ul>
<p>Finally there are a number of faults related to the DU resource
itself. These include:</p>
<ul>
<li>The UUID in the request not matching the format specified in RFC
4122 <span class="citation" data-cites="RFC4122"><a href="#ref-RFC4122"
role="doc-biblioref">[31]</a></span> Version 5 (Name-Based).</li>
<li>A corrupted DU resource, or the DU not being installable for other
reasons, such as not being signed by any trusted entity</li>
<li>The DU cannot be found in the data model. This fault can occur when
the request explicitly specifies the UUID (or combination of UUID and
version) of a DU that is unknown. It can also occur when the request
does not specify a UUID but explicitly specifies a URL that has never
been used to previously Install or Update a DU.</li>
<li>Attempting to downgrade the DU version.</li>
<li>Attempting to Update a DU not in the Installed state.</li>
<li>Updating the DU requiring more system resources, such as disk space,
memory, etc., than the device has available. Note that this error is not
to be used to indicate that more operations have been requested than the
device can support, which is indicated by the Resourced Exceeded USP
error (described above).</li>
</ul>
<h4 class="appendix4 auto-hoverlink" data-info="header"
id="sec:uninstall-faults">I.4.1.3 Uninstall Faults</h4>
<p>When there is a fault due to the Uninstall of a DU fault of any kind,
the DU does not transition to the Uninstalled state and no resources are
removed from the device. No changes are made to the EU-related portions
of the data model (including the EU Objects themselves and the related
Objects and Parameters that came into existence because of this DU).</p>
<p>There are Operation failures defined for Uninstall of a DU. They are
as follows:</p>
<ul>
<li>The EE on which the targeted DU resides is disabled. Note that if
the Uninstall operation targets DUs across multiple EEs, this fault will
occur if at least one of the EEs on which the DU resides is
disabled.</li>
<li>The DU cannot be found in the data model. If the EE is specified in
the request, this error occurs when there is no UUID (or UUID and
version) matching the one requested for the specified EE. If there is no
EE specified in the request, this error occurs when there is no UUID
matching the one in the requested on any EE in the data model, or, if
the version is also specified in the request, then this error occurs
when there is no DU with this combination of UUID and version on any EE
in the data model.</li>
<li>The UUID in the request not matching the format specified in RFC
4122 <span class="citation" data-cites="RFC4122"><a href="#ref-RFC4122"
role="doc-biblioref">[31]</a></span> Version 5 (Name- Based).</li>
<li>The DU caused an EE to come into existence on which at least 1 DU is
Installed.</li>
</ul>
<h3 class="appendix3 auto-hoverlink" data-info="header"
id="sec:eu-faults">I.4.2 EU Faults</h3>
<p>EU state transitions are triggered by the
<code>SetRequestedState()</code> command. One type of EU fault is a USP
Error Message sent in response to USP operate Message for the
<code>SetRequestedState()</code> command. The USP Error Message defined
are therefore simply a subset of the errors defined for the generic USP
Operate Message (e.g., Request Denied, Internal Error).</p>
<p>Note that there is one case specific to Software Module Management:
if a Controller tries to Start an EU on a disabled EE using the
<code>SetRequestedState()</code> command, the device returns a
“<code>7012 Invalid Value</code>” error response to the command
request.</p>
<p>There are also Software Module Management specific faults indicated
in the <code>ExecutionFaultCode</code> and
<code>ExecutionFaultMessage</code> Parameters in the data model. In
addition to providing software module specific fault information, this
Parameter is especially important in a number of scenarios:</p>
<ul>
<li>Errors that occur at a later date than the original USP Message,
such as a Dependency Failure that occurs several days after successful
Start of an EU because a DU providing dependencies is later
Uninstalled.</li>
<li>State transition errors that are triggered by the Autostart/Run
level mechanism.</li>
<li>“Autonomous” state transitions triggered outside the purview of USP,
such as by a LAN-side protocol.</li>
</ul>
<p>The faults in the <code>ExecutionFaultCode</code> Parameter are
defined as follows:</p>
<ul>
<li><code>FailureOnStart</code> – the EU failed to start despite being
requested to do so by the Controller.</li>
<li><code>FailureOnAutoStart</code> – the EU failed to start when
enabled to do so automatically.</li>
<li><code>FailureOnStop</code> – the EU failed to stop despite being
requested to do so by the Controller.</li>
<li><code>FailureWhileActive</code> – an EU that had previously
successfully been started either via an explicit transition or
automatically later fails.</li>
<li><code>DependencyFailure</code> – this is a more specific fault
scenario in which the EU is unable to start or stops at a later date
because of unresolved dependencies</li>
<li><code>Unstartable</code> – some error with the EU resource, its
configuration, or the state of the associated DU or EE, such as the EE
being disabled, prevents it from being started.</li>
</ul>
<p>When the EU is not currently in fault, this Parameter returns the
value <code>NoFault</code>. The <code>ExecutionFaultMessage</code>
Parameter provides additional, implementation specific information about
the fault in question. The <code>ExecutionFaultCode</code> and
<code>ExecutionFaultMessage</code> Parameters are triggered Parameters.
In other words, it is not expected that an Controller could read this
Parameter before issuing a USP Message and see that there was a
Dependency Failure that it would attempt to resolve first. If a
Controller wants a notification when these Parameters change, the
Controller can subscribe to the ValueChange notification type with the
Parameters for the referenced EU.</p>
<h1 class="appendix1 auto-hoverlink" data-info="header"
id="sec:firmware-management-of-devices-with-usp-agents">Appendix II:
Firmware Management of Devices with USP Agents</h1>
<p>Many manufacturers build and deploy devices that are able to support
multiple firmware images (i.e. multiple firmware images can be installed
on an Agent at the same time). There are at least a couple of advantages
to this strategy:</p>
<ol type="1">
<li><p>Having multiple firmware images installed improves the robustness
and stability of the device because, in all likelihood, one of the
installed images will be stable and bootable. Should a device not be
able to boot a newly installed firmware image, it could have the ability
to attempt to boot from a different firmware image, thus allowing the
device to come back online.</p></li>
<li><p>Support for multiple firmware images offers the ability for the
service provider to have a new firmware downloaded (but not activated)
to the device at any point during the day, then perhaps requiring only a
Set Message and an Operate Message to invoke the Reboot command at some
later time (perhaps during a short maintenance window or when the device
is idle) to cause the device to switch over to the new firmware. Along
with reducing the impact on the subscriber, the ability to spread the
download portion a firmware upgrade over a longer period of time (eg,
the entire day or over several days) can help minimize the impact of the
upgrade on the provider’s network.</p></li>
</ol>
<p>This Appendix discusses how to utilize the firmware image table on a
device to support firmware upgrades whether the device supports multiple
instances or just a single instance.</p>
<h2 class="appendix2 auto-hoverlink" data-info="header"
id="sec:getting-the-firmware-image-onto-the-device">II.1 Getting the
firmware image onto the device</h2>
<p>A Controller can download a firmware image to an Agent by invoking
the <code>Download()</code> command (via the Operate Message) found
within an instance of the
<code>Device.DeviceInfo.FirmwareImage.{i}.</code> data model table. The
<code>Download()</code> command will cause the referenced file to be
downloaded into the firmware image instance being operated on, and it
will cause that file to be validated by the Agent (the validation
process would include any normal system validate of a firmware image as
well as the check sum validation provided in the <code>Download()</code>
command).</p>
<p>If an Agent only supports a single firmware image instance then a
Controller would invoke the <code>Download()</code> command on that
active firmware image instance using the <code>AutoActivate</code>
argument to immediately activate the new firmware after it has been
downloaded. Neither the <code>Device.DeviceInfo.BootFirmwareImage</code>
Parameter nor the
<code>Device.DeviceInfo.FirmwareImage.{i}.Activate()</code> command
would typically be implemented by a device that only supports a single
firmware image instance.</p>
<p>If an Agent supports more than a single firmware image instance then
a Controller would typically invoke the <code>Download()</code> command
on a non-active firmware image instance in an effort of preserving the
current firmware image in case of an error while upgrading the firmware.
A firmware image instance is considered active if it is the currently
running firmware image.</p>
<h2 class="appendix2 auto-hoverlink" data-info="header"
id="sec:using-multiple-firmware-images">II.2 Using multiple firmware
images</h2>
<p>This section discusses the added functionality available when a
device supports two or more instances in the
<code>Device.DeviceInfo.FirmwareImage.{i}.</code> data model table.</p>
<h3 class="appendix3 auto-hoverlink" data-info="header"
id="sec:switching-firmware-images">II.2.1 Switching firmware images</h3>
<p>Once a device has multiple firmware images downloaded, validated, and
available, a Controller can use the data model to query what images are
on the device, which image is active, and configure which image to
activate.</p>
<p>A Controller can activate a new firmware image by following one of
two different procedures: (A) the Controller can modify the
<code>Device.DeviceInfo.BootFirmwareImage</code> Parameter to point to
the <code>Device.DeviceInfo.FirmwareImage.{i}.</code> Object Instance
that contains the desired firmware image and then reboot the device by
invoking an <code>Operate</code> Message with a <code>Reboot()</code>
command or (B) the Controller can invoke an Operate Message with an
<code>Activate()</code> command against the desired
<code>FirmwareImage</code> instance.</p>
<p>When attempting to get a device to switch to a different firmware
image, it is recommended that the Controller either subscribe to a
<code>ValueChange</code> notification on the
<code>DeviceInfo.SoftwareVersion</code> Parameter or subscribe to the
<code>Boot!</code> Event notification. If the Software Version value has
not changed or the <code>Boot!</code> Event’s
<code>FirmwareUpdated</code> argument is false, it could be an
indication that the device had problems booting the target firmware
image.</p>
<h3 class="appendix3 auto-hoverlink" data-info="header"
id="sec:performing-a-delayed-firmware-upgrade">II.2.2 Performing a
delayed firmware upgrade</h3>
<p>One of the benefits to having support for multiple firmware images on
a device is that it provides an opportunity to push a firmware image to
a device and then have the device switch to that image at a later time.
This functionally allows a service provider to push a firmware image to
a set of devices at any point during the day and then use a maintenance
window to switch all of the target devices to the target firmware.</p>
<p>This ability is of value because normally the download of the
firmware and the switch to the new image would both have to take place
during the maintenance window. Bandwidth limitations may have an impact
on the number of devices that can be performing the download at the same
time. If this is the case, the number of devices that can be upgrading
at the same time may be lower than desired, requiring multiple
maintenance windows to complete the upgrade. However, support for
multiple firmware images allows for the service provider to push
firmware images over a longer period of time and then use a smaller
maintenance window to tell the device to switch firmware images. This
can result is shorter system-wide firmware upgrades.</p>
<h3 class="appendix3 auto-hoverlink" data-info="header"
id="sec:recovering-from-a-failed-upgrade">II.2.3 Recovering from a
failed upgrade</h3>
<p>Another benefit of having multiple firmware images on a device is
that if a device cannot boot into a target firmware image because of
some problem with the image, the device could then try to boot one of
the other firmware images.</p>
<p>When there are two images, the device would simply try booting the
alternate image (which, ideally, holds the previous version of the
firmware). If there are more than two images, the device could try
booting from any of the other available images. Ideally, the device
would keep track of and try to boot from the previously known working
firmware (assuming that firmware is still installed on the device).</p>
<p>If the activation of a firmware image causes the device to lose its
USP Agent connectivity to the controller for any reason (i.e., the USP
Agent fails to send messages to the Controller, or the messages are not
understood by the Controller), the device is expected to roll back to
the previously activated image and add appropriate information to the
<code>Device.DeviceInfo.FirmwareImage.{i}.BootFailureLog</code>
parameter of the failed image.</p>
<p>Should the device boot a firmware image other than that specified via
the <code>Device.DeviceInfo.BootFirmwareImage</code> Parameter, it is
important that the device not change the value of the
<code>Device.DeviceInfo.BootFirmwareImage</code> Parameter to point to
the currently-running firmware image Object. If the device was to change
this Parameter value, it could make troubleshooting problems with a
firmware image switch more difficult.</p>
<p>It was recommended above that the Controller keep track of the value
of <code>Device.DeviceInfo.SoftwareVersion</code> Parameter or the
<code>FirmwareUpdated</code> flag in the <code>Boot!</code> event. If
the version changes unexpectedly or the <code>FirmwareUpdated</code>
flag is set to <code>true</code>, it could be an indication that the
device had problems booting a particular firmware image.</p>
<h1 class="appendix1 auto-hoverlink" data-info="header"
id="sec:device-proxy">Appendix III: Device Proxy</h1>
<p>This appendix describes a Theory of Operations for the
<code>Device.ProxiedDevice.</code> Object defined in the Device:2 Data
Model <span class="citation" data-cites="TR-181"><a href="#ref-TR-181"
role="doc-biblioref">[3]</a></span>.</p>
<p>The <code>Device.ProxiedDevice</code> table is defined as:</p>
<blockquote>
<p>“Each entry in the table is a ProxiedDevice Object that is a mount
point. Each ProxiedDevice represents distinct hardware Devices.
ProxiedDevice Objects are virtual and abstracted representation of
functionality that exists on hardware other than that which the Agent is
running.”</p>
</blockquote>
<p>An implementation of the <code>Device.ProxiedDevice.</code> Object
may be used in an IoT Gateway that proxies devices that are connected to
it via technologies other than USP such as Z-Wave, ZigBee, Wi-Fi, etc.
By designating a table of <code>ProxiedDevice</code> Objects, each
defined as a mount point, this allows a data model with Objects that are
mountable to be used to represent the capabilities of each of the
<code>ProxiedDevice</code> table instances.</p>
<p>For example, if <code>Device.WiFi.</code> and
<code>Device.TemperatureStatus.</code> Objects are modeled by the Agent,
then <code>Device.ProxiedDevice.1.WiFi.Radio.1.</code> models a
distinctly separate hardware device and has no relationship with
<code>Device.WiFi.Radio.1.</code>. The <code>ProxiedDevice</code>
Objects may each represent entirely different types of devices each with
a different set of Objects. The
<code>ProxiedDevice.1.TemperatureStatus.TemperatureSensor.1.</code>
Object has no physical relationship to
<code>ProxiedDevice.2.TemperatureStatus.TemperatureSensor.1.</code> as
they represent temperature sensors that exist on separate hardware. The
mount point allows <code>Device.ProxiedDevice.1.WiFi.Radio.</code> and
<code>Device.ProxiedDevice.1.TemperatureStatus.TemperatureSensor.</code>
to represent the full set of capabilities for the device being proxied.
This provides a Controller a distinct path to each
<code>ProxiedDevice</code> Object.</p>
<h1 class="appendix1 auto-hoverlink" data-info="header"
id="sec:communications-proxying">Appendix IV: Communications
Proxying</h1>
<p>This appendix describes a variety of proxies that can be created and
deployed in order to enhance the USP experience.</p>
<p>The types of proxies described are:</p>
<ul>
<li>Discovery Proxy: proxies discovery and advertisement; does not proxy
USP messages</li>
<li>Connectivity Proxy: proxies USP messages at the IP layer; does not
care about MTP or USP message headers or content; may do message caching
for sleeping devices</li>
<li>MTP Proxy: proxies USP messages at the MTP layer and below; does not
care about USP Message headers or content; may do message caching for
sleeping devices [<em>Note: The MTP Proxy may choose to look at the USP
Record to get information related to USP Endpoints, especially when
proxying WebSocket MTP.</em>]</li>
<li>USP to Non-USP Proxy: Proxies between USP and a non-USP management
or control protocol</li>
</ul>
<h2 class="appendix2 auto-hoverlink" data-info="header"
id="sec:proxying-building-block-functions">IV.1 Proxying Building Block
Functions</h2>
<p>These proxies are comprised of one or more of the building block
functions described in <a href="#tbl:proxy-building-block-functions"
class="table">Table 1</a>.</p>
<table id="tbl:proxy-building-block-functions">
<caption><div class="auto-hoverlink"
data-anchor="tbl:proxy-building-block-functions">
Table 1: Proxy Building Block Functions
</div></caption>
<colgroup>
<col style="width: 42%" />
<col style="width: 57%" />
</colgroup>
<thead>
<tr class="header">
<th>Function</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><em>L3/4 Translation Function</em></td>
<td>Translates up to and including the IP and transport layer (e.g.,
UDP, TCP) protocol headers, while leaving all higher layer protocol
headers and payloads untouched.</td>
</tr>
<tr class="even">
<td><em>MTP Translation Function</em></td>
<td>Translates up to and including the Message Transfer Protocol (MTP)
header, while leaving the USP Record untouched. Requires knowledge of
how to bind USP to two or more MTPs.</td>
</tr>
<tr class="odd">
<td><em>USP to non-USP Translation Function</em></td>
<td>Translates all headers and the USP Record and USP Message into data
model and headers of another management protocol. Requires proxy to have
an Agent.</td>
</tr>
<tr class="even">
<td><em>Caching Function</em></td>
<td>Can hold on to USP Messages intended for Endpoints that are
intermittently connected, until a time when that Endpoint is connected.
The USP Message is not altered, so no Endpoint is required to be aware
of the existence of this function.</td>
</tr>
<tr class="odd">
<td><em>Non-USP Advertisement Function</em></td>
<td>Responds to discovery queries using protocols other than USP (e.g.,
DNS-SD, DNS, DHCP) on behalf of Endpoints. May include a DNS Server. See
Discovery section for formatting of various non-USP discovery protocols
in the context of USP.</td>
</tr>
<tr class="even">
<td><em>Non-USP Discovery Function</em></td>
<td>Discovers Endpoints through discovery queries using protocols other
than USP. See Discovery section for formatting of various non-USP
discovery protocols in the context of USP.</td>
</tr>
<tr class="odd">
<td><em>Agent USP Advertisement Function</em></td>
<td>Maintains a USP data model table of discovered Agents. Requires an
Agent.</td>
</tr>
</tbody>
</table>
<h2 class="appendix2 auto-hoverlink" data-info="header"
id="sec:discovery-proxy">IV.2 Discovery Proxy</h2>
<p>A Discovery Proxy simply repeats the exact information that it
discovers from Endpoints. This is particularly useful in a multi-segment
LAN, where mDNS messages do not cross segment boundaries. The DNS-SD
Discovery Proxy <span class="citation" data-cites="RFC8766"><a
href="#ref-RFC8766" role="doc-biblioref">[39]</a></span> functionality
is recommended as a component of a Discovery Proxy. When used inside a
LAN, this would need the <em>Non-USP Discovery Function</em> and the
<em>Non-USP Advertisement Function</em> described in <a
href="#tbl:proxy-building-block-functions" class="table">Table
1</a>.</p>
<p>An <em>Agent USP Advertisement Function</em> would be needed to
support Endpoints in different networks (e.g., discovery of Agents on
the LAN by a Controller on the WAN).</p>
<p>USP Messages between proxied Endpoints go directly between the
Endpoints and do not go across the Discovery Proxy. The Discovery Proxy
has no role in USP outside discovery.</p>
<h2 class="appendix2 auto-hoverlink" data-info="header"
id="sec:connectivity-proxy">IV.3 Connectivity Proxy</h2>
<p>This describes proxying of discovery and IP connectivity of Endpoints
that need IP address or port translation to communicate, and/or do not
maintain continual IP connectivity. The Connectivity Proxy may cache USP
Messages on behalf of Endpoints that do not maintain continual
connectivity. The USP Message is not processed by the proxy function,
but it does go through the proxy for address translation or so it can be
cached, if necessary. Therefore, the connectivity information provided
by the Connectivity Proxy directs IP packets (that contain the USP
Records) be sent to the proxy and not to the destination IP address of
the Endpoint being proxied.</p>
<p>Both Endpoints must be using the same MTP. This Proxy translates the
IP address (and possibly the TCP or UDP port) from the Connectivity
Proxy to the proxied Endpoint, but does not touch (or need to
understand) the MTP headers or USP Message.</p>
<p>It is also possible to combine the caching functionality with the MTP
Proxy, by adding the <em>Caching Function</em> to the MTP Proxy (see
Section 3).</p>
<p>In order to serve as a Connectivity Proxy, the following functions
(from <a href="#tbl:proxy-building-block-functions" class="table">Table
1</a>) are needed: 1. <em>L3/4 Translation Function</em> 1. Depending on
whether the proxy is on the same network as the proxied Endpoints: 1.
<em>Non-USP Discovery Function</em> and/or otherwise
determined/configured knowledge of Agent(s) 1. <em>Non-USP Advertisement
Function</em> and/or <em>Agent USP Advertisement Function</em></p>
<p>The Connectivity Proxy can also include the <em>Caching Function</em>
to support Endpoints with intermittent connectivity.</p>
<h2 class="appendix2 auto-hoverlink" data-info="header"
id="sec:message-transfer-protocol-mtp-proxy">IV.4 Message Transfer
Protocol (MTP) Proxy</h2>
<p>This describes proxying between two USP Endpoints that do not support
a common MTP. The USP Record is untouched by the proxy function. MTP and
IP headers are changed by the proxy.</p>
<p>In order to serve as a MTP Proxy, the following functions (from <a
href="#tbl:proxy-building-block-functions" class="table">Table 1</a>)
are needed:</p>
<ol type="1">
<li><em>MTP Translation Function</em></li>
<li>Depending on whether it is on the same network as the proxied Agents
and/or the Controller that wants to communicate with those Agents:
<ol type="1">
<li><em>Non-USP Discovery Function</em> and/or otherwise
determined/configured knowledge of Agent(s)</li>
<li><em>Non-USP Advertisement Function</em> and/or <em>Agent USP
Advertisement Function</em></li>
</ol></li>
</ol>
<p>The MTP Proxy can also include the <em>Caching Function</em> to
support Endpoints with intermittent connectivity.</p>
<h3 class="appendix3 auto-hoverlink" data-info="header"
id="sec:mtp-header-translation-algorithms">IV.4.1 MTP Header Translation
Algorithms</h3>
<p>In order to implement a meaningful translation algorithm, the MTP
Proxy will need to:</p>
<ol type="1">
<li>Maintain mapping of discovered or configured Endpoint information to
information the MTP Proxy generates or is configured with. This allows
it to advertise that Endpoint on a different MTP and to translate the
MTP when it receives a message destined for that Endpoint.</li>
<li>Maintain a mapping of received “reply to” and other connection
information to connection and “reply to” information included by the MTP
Proxy in the sent message. This allows it to translate the MTP when it
receives a response message destined for that Endpoint.</li>
<li>Identify the target Endpoint for a received message.</li>
</ol>
<p>The following information will need to be stored in a maintained
mapping for an Endpoint:</p>
<ol type="1">
<li>URL -or- the IP Address (es) (IPv4 and/or IPv6) and UDP or TCP ports
-or- the socket for an established connection (note that the information
and configured data needed to establish this connection is out-of-scope
of this specification)</li>
<li>MTP-specific destination information (including destination
resource)
<ol type="1">
<li>For CoAP, this is the uri-path of the CoAP server Endpoint
resource</li>
<li>For WebSocket, this is either an established WebSocket connection or
the WebSocket server Endpoint resource</li>
<li>For STOMP, this is the STOMP destination of the Endpoint</li>
<li>For MQTT, this is a Topic that is subscribed to by the Endpoint</li>
</ol></li>
</ol>
<p>This mapping information is used to construct important parts of the
sent IP, UDP/TCP, and MTP headers. Other information used to construct
these headers may come from the received MTP Headers or even the
received USP Record.</p>
<p>The following table describes possible ways to accomplish the
activities for proxying from or to a particular MTP, and possible
sources of information. Other possibilities for proxying between two
MTPs may also exist. This table is not normative and is not intended to
constrain implementations.</p>
<table id="tbl:possible-mtp-proxy-methods">
<caption><div class="auto-hoverlink"
data-anchor="tbl:possible-mtp-proxy-methods">
Table 2: Possible MTP Proxy Methods
</div></caption>
<colgroup>
<col style="width: 6%" />
<col style="width: 17%" />
<col style="width: 40%" />
<col style="width: 35%" />
</colgroup>
<thead>
<tr class="header">
<th>MTP</th>
<th>Activity</th>
<th>when Proxying from</th>
<th>when Proxying to</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>CoAP</td>
<td>Maintain mapping of discovered/configured info to advertised
info</td>
<td>store discovered CoAP path/url/IP address/port with “reply to”
and/or connectivity info for other MTP</td>
<td>generate a CoAP <em>uri-path</em> for discovered info</td>
</tr>
<tr class="even">
<td></td>
<td>Maintain mapping of received info</td>
<td>store received <em>uri-query reply-to</em> CoAP Parameter with
“reply to” and/or connectivity info of the sent message</td>
<td>store the supplied “reply to” and/or connectivity info with a
generated CoAP <em>uri-path</em></td>
</tr>
<tr class="odd">
<td></td>
<td>Identify target USP Endpoint for a received message</td>
<td>possible source: received CoAP <em>uri-path</em></td>
<td>put value from a maintained mapping in <em>uri-path</em> and use IP
address and port from mapping</td>
</tr>
<tr class="even">
<td>WebSocket</td>
<td>Maintain mapping of discovered/configured info to advertised
info</td>
<td>store WebSocket connection info (and Endpoint ID, if socket is used
for more than one Endpoint) with “reply to” and/or connectivity info for
other MTP</td>
<td>establish WebSocket connection or associate Endpoint with existing
connection, for discovered info</td>
</tr>
<tr class="odd">
<td></td>
<td>Maintain mapping of received info</td>
<td>store WebSocket connection info (and Endpoint ID, if socket is used
for more than one Endpoint) with “reply to” and/or connectivity info for
other MTP</td>
<td>store the supplied “reply to” and/or connectivity info with a
WebSocket connection (and Endpoint ID, if socket is used for more than
one Endpoint)</td>
</tr>
<tr class="even">
<td></td>
<td>Identify target USP Endpoint for a received message</td>
<td>possible source: WebSocket connection established per proxied
Endpoint<br />
possible source: to_id in USP Record</td>
<td>send over WebSocket connection associated with the proxied
Endpoint</td>
</tr>
<tr class="odd">
<td>STOMP</td>
<td>Maintain mapping of discovered/configured info to advertised
info</td>
<td>store subscribed-to STOMP destination with “reply to” and/or
connectivity info for other MTP</td>
<td>subscribe to STOMP destination for discovered info</td>
</tr>
<tr class="even">
<td></td>
<td>Maintain mapping of received info</td>
<td>store <em>reply-to-dest</em> STOMP header (and associated STOMP
connection) with “reply to” or socket info of the sent message</td>
<td>store the supplied “reply to” and/or connectivity info with
subscribed-to STOMP destination and connection</td>
</tr>
<tr class="odd">
<td></td>
<td>Identify target USP Endpoint for a received message</td>
<td>possible source: received STOMP <em>destination</em><br />
possible source: to_id in USP Record</td>
<td>put value from maintained mapping in STOMP destination header and
use STOMP connection from that mapping</td>
</tr>
<tr class="even">
<td>MQTT</td>
<td>Maintain mapping of discovered/configured info to advertised
info</td>
<td>store subscribed-to Topic (Filter) with “reply to” and/or
connectivity info for other MTP</td>
<td>subscribe to MQTT Topic (Filter) for discovered info (if Topic
Filter, know which specific Topic to use for “reply to” info)</td>
</tr>
<tr class="odd">
<td></td>
<td>Maintain mapping of received info</td>
<td>store Response Topic or other provided “reply to” info (and
associated MQTT connection) with “reply to” or connectivity info of the
sent message</td>
<td>store the supplied “reply to” and/or connectivity info with a
specific MQTT Topic (within subscribed-to Topic Filter) and
connection</td>
</tr>
<tr class="even">
<td></td>
<td>Identify target USP Endpoint for a received message</td>
<td>possible source: received MQTT <code>PUBLISH</code> Topic Name<br />
possible source: to_id in USP Record</td>
<td>put value from maintained mapping in MQTT <code>PUBLISH</code> Topic
Name and use MQTT connection from that mapping</td>
</tr>
</tbody>
</table>
<p><a href="#fig:example-of-mtp-proxy-in-lan-with-wan-controller"
class="figure">Figure 30</a> shows an example of how an MTP Proxy might
be used to proxy between an MTP used by a Cloud Server in the WAN and an
MTP used inside the LAN. It also shows proxying between MTPs and
internal APIs used to communicate with multiple Agents internal to the
Services Gateway.</p>
<figure id="fig:example-of-mtp-proxy-in-lan-with-wan-controller">
<img src="extensions/proxying/MTP-proxy-example.png"
id="img:example-of-mtp-proxy-in-lan-with-wan-controller"
alt="Example of MTP Proxy in LAN with WAN Controller" />
<figcaption><div class="auto-hoverlink"
data-anchor="fig:example-of-mtp-proxy-in-lan-with-wan-controller">
Figure 30: Example of MTP Proxy in LAN with WAN Controller
</div></figcaption>
</figure>
<h3 class="appendix3 auto-hoverlink" data-info="header"
id="sec:coap-stomp-mtp-proxy-example-message-flow">IV.4.2 CoAP / STOMP
MTP Proxy Example Message Flow</h3>
<p>The following example is provided as a detailed look at a sample CoAP
(LAN) / STOMP (WAN) MTP Proxy to describe one possible way to do
discovery, connectivity and security. This example makes several
assumptions as to the nature of the STOMP connection between the MTP
Proxy and the STOMP server, which is completely undefined. It also makes
assumptions about implemented, enabled and configured Agent
capabilities.</p>
<p>Assumptions include: * a STOMP connection per proxied device * the
STOMP server supplies a subscribe-dest header in CONNECTED frames (this
is optional for a STOMP server) * there exists some means for the
Controller to discover the proxied Agent connection to the STOMP server
* the CoAP Agent does mDNS advertisement (optional but recommended
behavior) * the CoAP Agent and Proxy support and have enabled DTLS * the
CoAP Agent has been configured with the Proxy’s certificate for use as a
Trusted Broker. * the proxy uses the subscribe-dest value (supplied by
the STOMP server) as the value for the reply-to-dest header.</p>
<figure id="fig:coap-stomp-mtp-proxy-example-flow">
<img src="extensions/proxying/CoAP-STOMP-MTP-proxy-example.png"
id="img:coap-stomp-mtp-proxy-example-flow"
alt="CoAP-STOMP MTP Proxy Example Flow" />
<figcaption><div class="auto-hoverlink"
data-anchor="fig:coap-stomp-mtp-proxy-example-flow">
Figure 31: CoAP-STOMP MTP Proxy Example Flow
</div></figcaption>
</figure>
<p><strong>Controller connects to the STOMP server</strong></p>
<p><strong>A / B / C</strong> At any point prior to #5 the USP
Controller Endpoint ctrl1 connects to STOMP and subscribes to
destination A</p>
<ul>
<li>OUT OF SCOPE how the USP Endpoint ctrl1 destination A is discovered
by Proxy</li>
<li>OUT OF SCOPE how the proxied USP Endpoint agent1 STOMP destination Y
is discovered by USP Endpoint ctrl1</li>
</ul>
<p>Agent appears on network and Proxy allows Controller to communicate
with Agent</p>
<p><strong>#1</strong> The USP Endpoint agent1 appears on the network.
Proxy receives advertisement and gets the USP Endpoint identifier
“agent1” of the Agent (retrieved from mDNS advertisement see <a
href="#r-dis.8" class="requirement">R-DIS.8</a>).</p>
<p><strong>#2</strong> Proxy sends a CONNECT frame to the STOMP server
with endpoint-id header of “agent1”.</p>
<p><strong>#3</strong> Proxy receives a subscribe-dest header in the
CONNECTED frame identifying the STOMP destination it needs to subscribe
to on behalf of agent1.</p>
<p><strong>#4</strong> The Proxy sends a SUBSCRIBE frame to the STOMP
server with destination:Y and stores a mapping of USP Endpoint agent1
with coaps://&lt;Agent IP&gt;:&lt;port&gt;/agent1 to this STOMP
connection with destination Y.</p>
<p><strong>#5 / #6</strong> USP Endpoint ctrl1 initiates USP message to
agent. Proxy creates a STOMP reply-to-dest:A (on this STOMP connection)
to coaps://&lt;Proxy IP&gt;:&lt;port&gt;/destA mapping.</p>
<p><strong>#7/ #7.1</strong> Proxy takes USP Record from the STOMP frame
and sends it in a CoAP payload with CoAP URI coming from the step #4
mapping of STOMP destination Y to coap://&lt;Agent
IP&gt;:&lt;port&gt;/agent1. To secure the communication, the proxy and
Agent establish a DTLS session (exchange certificates) and the Agent
determines whether the proxy is a Trusted Broker.</p>
<p><strong>#8 / #8.1</strong> USP Endpoint agent1 sends a USP Record in
reply to ctrl1 using CoAP, to coaps://&lt;Proxy
IP&gt;:&lt;port&gt;/destA.</p>
<p><strong>#9 / #10</strong> Proxy takes USP Record from the CoAP
payload and sends it in a STOMP SEND frame using the mapping (created in
steps #5 / #6) of coaps://&lt;Proxy IP&gt;:&lt;port&gt;/destA to STOMP
destination A (and associated STOMP connection) created in steps #5 / #6
.</p>
<p><strong>Agent sends Notify Message to Controller</strong></p>
<p>These steps include the following additional assumptions: *
Controller has configured Agent with a notification subscription. *
Controller configured Agent with CoAP MTP information for itself. *
Proxy replies to mDNS queries for Controller with “ctrl1” Instance.
Controller was able to assume or otherwise determine that Proxy would do
this and that its proxied CoAP connection would be discoverable by
querying for ctrl1._usp-ctrl-coap._udp._local. * Proxy can use the
previous reply-to-dest header value to reach this Controller</p>
<p><strong>#11</strong> The Agent sends mDNS query for
ctrl1._usp-ctrl-coap._udp._local.</p>
<p><strong>#12</strong> The Proxy response to the Agent includes TXT
record with path of coaps://&lt;Proxy IP&gt;:&lt;port&gt;/ctrl1. This
provides a URL for the Agent to use to send a Notify Message to the
Controller.</p>
<p><strong>#13 / #13.1</strong> The Agent sends a Notify Message to
Controller at coaps://&lt;Proxy IP&gt;:&lt;port&gt;/ctrl1.</p>
<p><strong>#14 / #15</strong> Proxy takes the USP Record from the CoAP
payload and sends it in a STOMP SEND frame using the mapping (stored in
#5 / #6 ) of coaps://&lt;Proxy IP&gt;:&lt;port&gt;/destA to STOMP
destination:A (and associated STOMP connection).</p>
<h2 class="appendix2 auto-hoverlink" data-info="header"
id="sec:usp-to-non-usp-proxy">IV.5 USP to Non-USP Proxy</h2>
<p>This describes proxying between a Controller and some other
management protocol with its own data model schema (e.g., UPnP DM,
ZigBee, NETCONF, RESTCONF). In this case the proxy is expected to
maintain a USP representation of the non-USP data. This requires the
proxy to expose itself as a full Agent to the Controller. See the <a
href="#sec:device-proxy" class="heading">Device Proxy appendix</a> for
the Theory of Operations for the <code>Device.ProxiedDevice.</code>
Object defined in the Device:2 Data Model <span class="citation"
data-cites="TR-181"><a href="#ref-TR-181"
role="doc-biblioref">[3]</a></span>.</p>
<p>In order to serve as a USP to non-USP Proxy, the <em>USP to non-USP
Translation Function</em> (from <a
href="#tbl:proxy-building-block-functions" class="table">Table 1</a>) is
needed.</p>
<h1 class="appendix1 auto-hoverlink" data-info="header"
id="sec:iot-data-model-theory-of-operation">Appendix V: IoT Data Model
Theory of Operation</h1>
<h2 class="appendix2 auto-hoverlink" data-info="header"
id="sec:introduction-2">V.1 Introduction</h2>
<p>Since there are thousands of different Internet of Things (IoT)
devices, the data model needs a flexible modular way to support them
using generic building block templates. To achieve this, an IoT device
is represented in the data model by sensor and control capabilities:</p>
<ul>
<li>Sensor capabilities, which allow reading a state, e.g. a temperature
value, a battery level, a light color, etc.</li>
<li>Control capabilities, which allow changing a value, e.g. set a
temperature, switch a light etc.</li>
</ul>
<p>The Device:2 Data Model <span class="citation" data-cites="TR-181"><a
href="#ref-TR-181" role="doc-biblioref">[3]</a></span> defines
capability Objects that reflect capabilities found on many different
devices (example: BinaryControl). By using these Objects, a large
ecosystem of devices can be described using a small set of capabilities
(see table below).</p>
<h2 class="appendix2 auto-hoverlink" data-info="header"
id="sec:iot-data-model-overview">V.2 IoT data model overview</h2>
<p>The figure shows the overall structure of the IoT data model:</p>
<figure id="fig:iot-data-model">
<img src="extensions/iot/./figure-73.png" id="img:iot-data-model"
alt="IoT Data Model" />
<figcaption><div class="auto-hoverlink"
data-anchor="fig:iot-data-model">
Figure 32: IoT Data Model
</div></figcaption>
</figure>
<p>The data model defines an IoT Capability table, whose instances
describe the IoT device’s exposed capabilities. The capability table can
appear directly under the <code>Device.</code> Object (if the IoT device
hosts a USP Agent) or under a <code>Device.ProxiedDevice.{i}.</code> or
<code>Device.ProxiedDevice.{i}.Node.{i}.</code> instance.</p>
<h3 class="appendix3 auto-hoverlink" data-info="header"
id="sec:iot-capability-table">V.2.1 IoT Capability table</h3>
<p>A capability is represented in the <code>Device.IoTCapability.</code>
table as a generic Object Instance with a specific class, and an
instantiated Sub-Object depending on this class. The class name is
defined by the Sub-Object name in a <code>Class</code> Parameter for
each IoT Capability table entry, to allow the Controller to detect the
instantiated Sub-Object.</p>
<p>Only one out of the following Sub-Objects can exist per instance:</p>
<table>
<colgroup>
<col style="width: 34%" />
<col style="width: 65%" />
</colgroup>
<thead>
<tr class="header">
<th>Capability Sub-Object</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><code>BinaryControl</code></td>
<td>Allows setting a binary value (e.g. on or off)</td>
</tr>
<tr class="even">
<td><code>LevelControl</code></td>
<td>Allows setting a continuous value in a predefined range</td>
</tr>
<tr class="odd">
<td><code>EnumControl</code></td>
<td>Allows setting a value from a predefined set of values</td>
</tr>
<tr class="even">
<td><code>BinarySensor</code></td>
<td>Provides a binary reading value (true/false)</td>
</tr>
<tr class="odd">
<td><code>LevelSensor</code></td>
<td>Provides a continuous reading value</td>
</tr>
<tr class="even">
<td><code>MultiLevelSensor</code></td>
<td>Provides multiple reading values, which belong together</td>
</tr>
</tbody>
</table>
<p>Each IoT capability Sub-Object has a <code>Type</code> Parameter to
identify the functionality the capability is representing. See the <a
href="#sec:type-definition" class="heading">Type definition</a> section
for details.</p>
<h3 class="appendix3 auto-hoverlink" data-info="header"
id="sec:node-object-table">V.2.2 Node Object table</h3>
<p>The <code>Device.Node.{i}.</code> and
<code>Device.ProxiedDevice.{i}.Node.{i}.</code> Objects are mount points
that provide the ability to support complex devices - that is, a group
of capabilities. Each node is a container for a group of device
capabilities that have a direct relationship with each other
(sub-device) and a hierarchal relationship with the top-level. A node
may have the same capabilities as the top-level, but applicable only for
the node, with no impact to the top-level. Capabilities for the
top-level node may have an effect on the lower level nodes, such as
power.</p>
<h2 class="appendix2 auto-hoverlink" data-info="header"
id="sec:architecture-mappings">V.3 Architecture mappings</h2>
<h3 class="appendix3 auto-hoverlink" data-info="header"
id="sec:individual-iot-devices">V.3.1 Individual IoT devices</h3>
<p>Stand-alone IoT devices, which are capable of supporting their own
USP Agent, provide their own data models, which expose the IoT sensor
and control capabilities of the device:</p>
<figure id="fig:iot-individual-device-models">
<img src="extensions/iot/./figure-74.png"
id="img:iot-individual-device-models"
alt="IoT individual device models" />
<figcaption><div class="auto-hoverlink"
data-anchor="fig:iot-individual-device-models">
Figure 33: IoT individual device models
</div></figcaption>
</figure>
<p>Each device registers as an individual entity to the USP Controller.
With the help of <code>Node</code> Objects, the capabilities can be
additionally structured (not shown in the picture).</p>
<h3 class="appendix3 auto-hoverlink" data-info="header"
id="sec:proxied-iot-devices">V.3.2 Proxied IoT devices</h3>
<p>IoT devices connected over a proxy protocol (e.g. ZigBee) with an IoT
control device hosting the USP Agent are modeled as proxied devices
(i.e., using the <code>Device.ProxiedDevice.</code> table) in the data
model of the control device’s USP Agent:</p>
<figure id="fig:iot-proxied-device-model">
<img src="extensions/iot/./figure-75.png"
id="img:iot-proxied-device-model" alt="IoT proxied device model" />
<figcaption><div class="auto-hoverlink"
data-anchor="fig:iot-proxied-device-model">
Figure 34: IoT proxied device model
</div></figcaption>
</figure>
<p>Each IoT device is represented as a
<code>Device.ProxiedDevice.{i}.</code> instance in the data model of the
control device, which exposes its IoT capabilities in the corresponding
Objects. The capabilities can be additionally structured with the help
of <code>Node</code> Object (not shown in the picture).</p>
<h2 class="appendix2 auto-hoverlink" data-info="header"
id="sec:iot-data-model-object-details">V.4 IoT data model Object
details</h2>
<h3 class="appendix3 auto-hoverlink" data-info="header"
id="sec:common-capability-parameters">V.4.1 Common capability
Parameters</h3>
<p>These Parameters have the same behavior for all capability
Sub-Objects, where defined.</p>
<h4 class="appendix4 auto-hoverlink" data-info="header"
id="sec:type-definition">V.4.1.1 Type definition</h4>
<p><strong>Applies to:</strong> All capability Sub-Objects</p>
<p>All capability Objects contain a mandatory <code>Type</code>
enumeration value.</p>
<p>The <code>Type</code> value is a predefined enumeration value with
the goal of giving a unified description of the capability Object. If
the <code>Type</code> value requires further detail, the
<code>Description</code> Parameter may provided a further
definition.</p>
<p><em>Note: The <code>Type</code> enumeration in the data model can
also, like all Parameters, be extended using the rules defined in TR-106
<span class="citation" data-cites="TR-106"><a href="#ref-TR-106"
role="doc-biblioref">[2]</a></span>.</em></p>
<h4 class="appendix4 auto-hoverlink" data-info="header"
id="sec:unit-definition">V.4.1.2 Unit definition</h4>
<p><strong>Applies to:</strong> LevelControl, LevelSensor,
MultilevelSensor</p>
<p>To define the used unit a similar concept as for the type definition
is used. The definition consists of the <code>Unit</code> enumeration
value.</p>
<p>The <code>Unit</code> value is a predefined enumeration value with
the goal of giving a unified representation of the used unit.</p>
<p><em>Note: The <code>Unit</code> enumeration in the data model can
also, like all Parameters, be extended using the rules defined in TR-106
<span class="citation" data-cites="TR-106"><a href="#ref-TR-106"
role="doc-biblioref">[2]</a></span>.</em></p>
<p><em>Note: Imperial units are intentionally not modeled in favor of
the metric system to increase the inter-working. If the Controller needs
imperial units, it can easily convert the metric units into imperial
ones by using the well-defined conversion routines.</em></p>
<h3 class="appendix3 auto-hoverlink" data-info="header"
id="sec:control-objects">V.4.2 Control Objects</h3>
<p>Control Objects represent IoT capabilities that involve the
manipulation of device or application states. They include Binary
Controls, Level Controls, and Enumerated Controls.</p>
<h4 class="appendix4 auto-hoverlink" data-info="header"
id="sec:binarycontrol">V.4.2.1 BinaryControl</h4>
<p>The binary controller defines the simplest type of controller, which
allows to switch between two values like true/false, on/off, full/empty,
etc. Its value is modeled as a Boolean, which can be either
<code>true</code> or <code>false</code>.</p>
<p>The minimum definition of a “BinaryControl” consists of:</p>
<pre><code>    IoTCapability.i.Class               = &quot;BinaryControl&quot;
    IoTCapability.i.BinaryControl.Type  = ...
    IoTCapability.i.BinaryControl.Value = ...</code></pre>
<p>The value can be changed either directly by a USP Set operation, or
via The <code>Toggle()</code> command, which corresponds to the behavior
of a switch, changing the value to the other state.</p>
<h4 class="appendix4 auto-hoverlink" data-info="header"
id="sec:levelcontrol">V.4.2.2 LevelControl</h4>
<p>The level controller capability allows a continuous change of a value
within a predefined range. Its capabilities are defined by these three
mandatory Parameters:</p>
<ul>
<li><code>Unit</code> - The unit used for the value</li>
<li><code>MinValue</code> - The minimum value the value can be set</li>
<li><code>MaxValue</code> - The maximum value the value can be set</li>
</ul>
<p>Implementations have to provide the minimum and maximum values to
allow the controller to detect what values can be applied.</p>
<p>The minimum definition of a “LevelControl” consists of:</p>
<pre><code>    IoTCapability.i.Class                 = &quot;LevelControl&quot;
    IoTCapability.i.LevelControl.Type     = ...
    IoTCapability.i.LevelControl.Unit     = ...
    IoTCapability.i.LevelControl.MinValue = ...
    IoTCapability.i.LevelControl.MaxValue = ...
    IoTCapability.i.LevelControl.Value    = ...</code></pre>
<p>The value can be changed either directly by a USP Set operation, or
via the step commands.</p>
<p>If the <code>StepUp()</code> command and/or the
<code>StepDown()</code> command are implemented, the
<code>StepValue</code> Parameter has to be implemented, which indicates
the amount of change triggered by a step command. If resulting value of
a step command would exceed the defined range, the operation does not
result in a failure - instead, the result is set to the range limit
value.</p>
<p>For example, if a temperature range is defined from 5.5 degC to 25
degC with a step value of 1 degC, a step down from 6 degC would result
in 5.5 degC and not in 5 degC.</p>
<p>Additionally, if the lowest possible value is already set, a
<code>StepDown()</code> will not change the current value, since the
defined minimum range would be exceeded. The same also applies to the
maximum value and <code>StepUp()</code> command.</p>
<h4 class="appendix4 auto-hoverlink" data-info="header"
id="sec:enumcontrol">V.4.2.3 EnumControl</h4>
<p>The enumeration controller capability allows setting one of a set of
predefined values. Examples are mode selections, with more than two
modes. If only two values exist, the binary controller Object is
preferred.</p>
<p>The minimum definition of an “EnumControl” consists of:</p>
<pre><code>    IoTCapability.i.Class                   = &quot;EnumControl&quot;
    IoTCapability.i.EnumControl.Type        = ...
    IoTCapability.i.EnumControl.ValidValues = &lt;list of possible values&gt;
    IoTCapability.i.EnumControl.Value       = &lt;current value&gt;</code></pre>
<p>The value can be changed either directly by a USP Set operation, or
via the step commands.</p>
<p>The step commands will cycle through the value range, meaning that if
the last valid value is reached, the next <code>StepUp()</code> command
will select the first value of the valid values and vice versa for the
<code>StepDown()</code> command. The valid values are stored in the
Parameter <code>ValidValues</code> as a comma-separated list; that order
of the list will be followed by the step commands.</p>
<p>It is possible to implement only one of the step commands, if only
one direction is needed.</p>
<h3 class="appendix3 auto-hoverlink" data-info="header"
id="sec:sensor-objects">V.4.3 Sensor Objects</h3>
<p>Sensor Objects represent IoT capabilities that involve reading or
reporting on a device or application state. They include Binary Sensors,
Level Sensors, and Enumerated Sensors, along with support for thresholds
and triggering events.</p>
<h4 class="appendix4 auto-hoverlink" data-info="header"
id="sec:binary-sensor">V.4.3.1 Binary Sensor</h4>
<p>The binary sensor Object Instance supports different kinds of binary
sensor operations:</p>
<ul>
<li>Simple binary state, e.g. a door or window state</li>
<li>Threshold trigger, e.g. trigger a Carbon Dioxide Alarm if a certain
threshold is exceeded.</li>
<li>Repeated trigger with grace period, e.g. movement detector.</li>
</ul>
<h5 class="appendix5 auto-hoverlink" data-info="header"
id="sec:simple-binary-state-sensor">V.4.3.1.1 Simple binary state
sensor</h5>
<p>To model a simple sensor, which changes between two distinct states
(e.g. a window or door open/close sensor), only the <code>Value</code>
Parameter is needed.</p>
<p>The minimum definition of a BinarySensor consists of:</p>
<pre><code>    IoTCapability.i.Class              = &quot;BinarySensor&quot;
    IoTCapability.i.BinarySensor.Type  = ...
    IoTCapability.i.BinarySensor.Value = {true/false}</code></pre>
<p>The values of <code>true</code> and <code>false</code> represent the
two possible <code>Value</code> states. Each time the state changes the
value toggles.</p>
<p>For example, a motion sensor would be modeled as:</p>
<pre><code>    IoTCapability.i.Class              = &quot;BinarySensor&quot;
    IoTCapability.i.BinarySensor.Type  = &quot;MotionDetected&quot;
    IoTCapability.i.BinarySensor.Value = true</code></pre>
<p>Note that binary sensor types are meaningful for binary state
behavior, e.g., “WindowOpen” rather than “Window”.</p>
<h5 class="appendix5 auto-hoverlink" data-info="header"
id="sec:threshold-trigger-sensor">V.4.3.1.2 Threshold trigger
sensor</h5>
<p>To model a sensor, which additionally triggers on a certain
threshold, add the <code>Sensitivity</code> Parameter to the
definition:</p>
<pre><code>    IoTCapability.1.Class                    = &quot;BinarySensor&quot;
    IoTCapability.1.BinarySensor.Type        = &quot;CarbonDioxideDetected&quot;
    IoTCapability.1.BinarySensor.Value       = {true/false}
    IoTCapability.1.BinarySensor.Sensitivity = 50</code></pre>
<p>With the <code>Sensitivity</code> Parameter, the threshold is
controlled. As soon as the measured value exceeds the threshold, the
<code>Value</code> Parameter is set to <code>true</code>. As soon as the
measured value goes below the threshold the <code>Value</code> Parameter
is set to <code>false</code>.</p>
<figure id="fig:iot-threshold-trigger-sensitivity">
<img src="extensions/iot/./figure-76.png"
id="img:iot-threshold-trigger-sensitivity"
alt="IoT threshold trigger sensitivity" />
<figcaption><div class="auto-hoverlink"
data-anchor="fig:iot-threshold-trigger-sensitivity">
Figure 35: IoT threshold trigger sensitivity
</div></figcaption>
</figure>
<p>The sensitivity value is a relative value in the range 0 to 100
percent. The exact meaning depends on the implementation.</p>
<h5 class="appendix5 auto-hoverlink" data-info="header"
id="sec:trigger-time-control">V.4.3.1.3 Trigger time control</h5>
<p>If the sensor state, after being triggered, should stay active for a
minimum period, the <code>HoldTime</code> Parameter is used:</p>
<pre><code>    IoTCapability.1.Class                    = &quot;BinarySensor&quot;
    IoTCapability.1.BinarySensor.Type        = &quot;CarbonDioxideDetected&quot;
    IoTCapability.1.BinarySensor.Value       = {true/false}
    IoTCapability.1.BinarySensor.Sensitivity = 50
    IoTCapability.1.BinarySensor.HoldTime    = 5000</code></pre>
<p>This figure shows the effect of the <code>HoldTime</code> Parameter
on the resulting value:</p>
<figure id="fig:iot-threshold-trigger-hold-time">
<img src="extensions/iot/./figure-77.png"
id="img:iot-threshold-trigger-hold-time"
alt="IoT threshold trigger hold time" />
<figcaption><div class="auto-hoverlink"
data-anchor="fig:iot-threshold-trigger-hold-time">
Figure 36: IoT threshold trigger hold time
</div></figcaption>
</figure>
<p>If the <code>HoldTime</code> Parameter is not implemented or is set
to <code>0</code>, the handling is disabled.</p>
<h5 class="appendix5 auto-hoverlink" data-info="header"
id="sec:repeated-trigger-with-grace-period">V.4.3.1.4 Repeated trigger
with grace period</h5>
<p>Some sensors might produce too many triggers, e.g. continuous
movement, when only one trigger in a specific time period is needed. To
filter these the <code>RestTime</code> Parameter is used:</p>
<pre><code>    IoTCapability.1.Class                    = &quot;BinarySensor&quot;
    IoTCapability.1.BinarySensor.Type        = &quot;CarbonDioxideDetected&quot;
    IoTCapability.1.BinarySensor.Value       = {true/false}
    IoTCapability.1.BinarySensor.Sensitivity = 50
    IoTCapability.1.BinarySensor.RestTime    = 10000</code></pre>
<p>With this setting, new trigger events are ignored for 10 seconds
(10000 miliseconds) after the first trigger has been detected, resulting
in the following pattern:</p>
<figure id="fig:iot-threshold-trigger-rest-time">
<img src="extensions/iot/./figure-78.png"
id="img:iot-threshold-trigger-rest-time"
alt="IoT threshold trigger rest time" />
<figcaption><div class="auto-hoverlink"
data-anchor="fig:iot-threshold-trigger-rest-time">
Figure 37: IoT threshold trigger rest time
</div></figcaption>
</figure>
<p>If the <code>RestTime</code> Parameter is not implemented or is set
to <code>0</code>, the handling is disabled.</p>
<h5 class="appendix5 auto-hoverlink" data-info="header"
id="sec:repeated-trigger-with-minimum-duration">V.4.3.1.5 Repeated
trigger with minimum duration</h5>
<p>To get readings with a minimum duration, combine rest and hold
times:</p>
<pre><code>    IoTCapability.1.Class                    = &quot;BinarySensor&quot;
    IoTCapability.1.BinarySensor.Type        = &quot;CarbonDioxideDetected&quot;
    IoTCapability.1.BinarySensor.Value       = {true/false}
    IoTCapability.1.BinarySensor.Sensitivity = 50
    IoTCapability.1.BinarySensor.HoldTime    = 5000
    IoTCapability.1.BinarySensor.RestTime    = 10000</code></pre>
<p>Which results in the following pattern:</p>
<figure id="fig:iot-threshold-trigger-minimum-duration">
<img src="extensions/iot/./figure-79.png"
id="img:iot-threshold-trigger-minimum-duration"
alt="IoT threshold trigger minimum duration" />
<figcaption><div class="auto-hoverlink"
data-anchor="fig:iot-threshold-trigger-minimum-duration">
Figure 38: IoT threshold trigger minimum duration
</div></figcaption>
</figure>
<h4 class="appendix4 auto-hoverlink" data-info="header"
id="sec:level-sensor">V.4.3.2 Level Sensor</h4>
<p>The <code>LevelSensor</code> Object provides a template for modeling
devices that report various levels. <code>LevelSensor</code> is used to
reflect the functionality of a sensor that reports a level in units and
supports different kinds of sensor operation:</p>
<ul>
<li>Level reading</li>
<li>Additional Threshold trigger: e.g., a Battery Alarm is
triggered.</li>
</ul>
<h5 class="appendix5 auto-hoverlink" data-info="header"
id="sec:level-reading">V.4.3.2.1 Level reading</h5>
<p>To model a level reading, the reading value and its unit are defined.
The minimum definition of a <code>LevelSensor</code> consists of:</p>
<pre><code>    IoTCapability.i.Class             = &quot;LevelSensor&quot;
    IoTCapability.i.LevelSensor.Type  = ...
    IoTCapability.i.LevelSensor.Unit  = ...
    IoTCapability.i.LevelSensor.Value = ...</code></pre>
<p>For example, to show the remaining load of a battery in percent, this
capability would have the following values:</p>
<pre><code>    IoTCapability.1.Class             = &quot;LevelSensor&quot;
    IoTCapability.1.LevelSensor.Type  = &quot;Battery&quot;
    IoTCapability.1.LevelSensor.Unit  = &quot;%&quot;
    IoTCapability.1.LevelSensor.Value = 63&quot;</code></pre>
<p>With this definition, the remaining load is expressed in percent,
here 63 percent. Since the unit value is a decimal type it is also
possible to specify fractions for the value:</p>
<pre><code>    IoTCapability.1.Class = &quot;LevelSensor&quot;
    IoTCapability.1.LevelSensor.Type  = &quot;Battery&quot;
    IoTCapability.1.LevelSensor.Unit  = &quot;%&quot;
    IoTCapability.1.LevelSensor.Value = 63.26</code></pre>
<p>This expresses a total remaining load of 63.26 percent.</p>
<h5 class="appendix5 auto-hoverlink" data-info="header"
id="sec:threshold-trigger">V.4.3.2.2 Threshold trigger</h5>
<p>In cases where not only the actual value is of interest, but also
important to know if a predefined threshold is reached or undershot, the
<code>LevelSensor</code> Object can be extended with threshold
Parameters. Once the <code>LowLevel</code> or <code>HighLevel</code>
Parameter is <code>true</code>, it will remain <code>true</code> until
the device is reset or the condition no longer exists. This will depend
on the particular device.</p>
<table>
<colgroup>
<col style="width: 28%" />
<col style="width: 9%" />
<col style="width: 5%" />
<col style="width: 56%" />
</colgroup>
<thead>
<tr class="header">
<th>Parameter</th>
<th>Type</th>
<th>R/W</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><code>LowLevel</code></td>
<td>boolean</td>
<td>R</td>
<td>True means that the low level threshold is reached or
undershot.</td>
</tr>
<tr class="even">
<td><code>LowLevelThreshold</code></td>
<td>decimal</td>
<td>R/W</td>
<td>The defined low level value.</td>
</tr>
<tr class="odd">
<td><code>HighLevel</code></td>
<td>boolean</td>
<td>R</td>
<td>True means that the high level threshold is reached or
exceeded.</td>
</tr>
<tr class="even">
<td><code>HighLevelThreshold</code></td>
<td>decimal</td>
<td>R/W</td>
<td>The defined high level value.</td>
</tr>
</tbody>
</table>
<p>Table 17 – IoT LevelSensor threshold Parameters</p>
<p>When modeling a battery with a <code>LevelSensor</code> Object, an
additional low level warning (Boolean) may be supported along with a Low
Level threshold that provides a setting for the warning. The resulting
Object looks like this:</p>
<pre><code>    IoTCapability.1.Class                         = &quot;LevelSensor&quot;
    IoTCapability.1.LevelSensor.Type              = &quot;Battery&quot;
    IoTCapability.1.LevelSensor.Unit              = &quot;%&quot;
    IoTCapability.1.LevelSensor.LowLevelThreshold = 20
    IoTCapability.1.LevelSensor.Value             = 19
    IoTCapability.1.LevelSensor.LowLevel          = true</code></pre>
<p><em>Note: For more complex scenarios, like having a grace period, the
binary sensor Object can be used instead of the LowLevel or HighLevel
Threshold Parameters.</em></p>
<h5 class="appendix5 auto-hoverlink" data-info="header"
id="sec:multi-level-sensor">V.4.3.2.3 Multi Level Sensor</h5>
<p>A <code>MultiLevelSensor</code> instance models sensors, which
provide a set of related values with the same unit.</p>
<p>The minimum definition of a “MultiLevelSensor” consists of:</p>
<pre><code>    IoTCapability.i.Class                   = &quot;MultiLevelSensor&quot;
    IoTCapability.i.MultiLevelSensor.Type   = ...
    IoTCapability.i.MultiLevelSensor.Unit   = ...
    IoTCapability.i.MultiLevelSensor.Values = ...
    IoTCapability.1.MultiLevelSensor.ValueNames = ...</code></pre>
<p>An example is a location reading consisting of the two values
longitude and latitude in decimal degree notation, which have to be read
together:</p>
<pre><code>    IoTCapability.1.Class                       = &quot;MultiLevelSensor&quot;
    IoTCapability.1.MultiLevelSensor.Type       = &quot;Location&quot;
    IoTCapability.1.MultiLevelSensor.Unit       = &quot;deg&quot;
    IoTCapability.1.MultiLevelSensor.Values     = &quot;48.1372056,11.57555&quot;
    IoTCapability.1.MultiLevelSensor.ValueNames = &quot;Latitude,Longitude&quot;</code></pre>
<p>This example uses the Parameter <code>ValueNames</code> to provide
information about the individual value meanings.</p>
<h4 class="appendix4 auto-hoverlink" data-info="header"
id="sec:enum-sensor">V.4.3.3 Enum Sensor</h4>
<p>An <code>EnumSensor</code> instance provides a reading value from a
predefined set of values. This allows modeling of sensors, which can
output discreet values from a predefined set.</p>
<p>The minimum definition of an “EnumSensor” consists of:</p>
<pre><code>    IoTCapability.i.Class                  = &quot;EnumSensor&quot;
    IoTCapability.i.EnumSensor.Type        = ...
    IoTCapability.i.EnumSensor.Unit        = ...
    IoTCapability.i.EnumSensor.ValidValues = ...
    IoTCapability.i.EnumSensor.Value       = ...</code></pre>
<p>The <code>ValidValues</code> Parameter determines the set of values,
which will be delivered by the sensor.</p>
<p>For example, a traffic light could be modeled as:</p>
<pre><code>    IoTCapability.1.Class                  = &quot;EnumSensor&quot;
    IoTCapability.1.EnumSensor.Type        = &quot;X_&lt;oui&gt;_TrafficLight&quot;
    IoTCapability.1.EnumSensor.ValidValues = &quot;Red, Yellow, Green&quot;
    IoTCapability.1.EnumSensor.Value       = &quot;Green&quot;</code></pre>
<h2 class="appendix2 auto-hoverlink" data-info="header"
id="sec:examples">V.5 Examples</h2>
<p>This chapter gives several examples how to model IoT Devices.</p>
<h3 class="appendix3 auto-hoverlink" data-info="header"
id="sec:example-ac-thermostat">V.5.1 Example: A/C Thermostat</h3>
<p>This example shows an A/C Thermostat connected over Z-Wave as a
proxied device of an IoT Gateway:</p>
<p>Structure elements:</p>
<ul>
<li>IoTCapability.1 (EnumControl) : Operation Mode</li>
<li>IoTCapability.2 (LevelControl) : Cool Temperature in range from 14
to 25 degC</li>
<li>IoTCapability.3 (LevelControl) : Heat Temperature in range from 14
to 25 degC</li>
<li>IoTCapability.4 (LevelControl) : Energy Saving Cool Temperature in
range from 14 to 25 degC</li>
<li>IoTCapability.5 (LevelControl) : Energy Saving Heat Temperature in
range from 14 to 25 degC</li>
<li>IoTCapability.6 (LevelSensor) : Current Temperature</li>
<li>IoTCapability.7 (EnumControl) : Fan Mode Control</li>
<li>IoTCapability.8 (EnumSensor) : Current Fan Operating State</li>
</ul>
<p>Instantiated data model:</p>
<pre><code>    ProxiedDevice.1.Type                                    = &quot;Thermostat&quot;
    ProxiedDevice.1.Online                                  = true
    ProxiedDevice.1.ProxyProtocol                           = &quot;Z-Wave&quot;

    ProxiedDevice.1.IoTCapabilityNumberOfEntries            = 9

    ProxiedDevice.1.IoTCapability.1.Class                   = &quot;EnumControl&quot;
    ProxiedDevice.1.IoTCapability.1.EnumControl.Type        = &quot;ThermostatMode&quot;
    ProxiedDevice.1.IoTCapability.1.EnumControl.Value       = &quot;Cool&quot;
    ProxiedDevice.1.IoTCapability.1.EnumControl.ValidValues = &quot;Heat, Cool,
                                                              Energy_heat,
                                                              Energy_cool, Off,
                                                              Auto&quot;

    ProxiedDevice.1.IoTCapability.2.Class                   = &quot;LevelControl&quot;
    ProxiedDevice.1.IoTCapability.2.LevelControl.Type       = &quot;Temperature&quot;
    ProxiedDevice.1.IoTCapability.2.LevelControl.Description = &quot;TargetCoolTemperature&quot;
    ProxiedDevice.1.IoTCapability.2.LevelControl.Value      = 17
    ProxiedDevice.1.IoTCapability.2.LevelControl.Unit       = &quot;degC&quot;
    ProxiedDevice.1.IoTCapability.2.LevelControl.MinValue   = 14
    ProxiedDevice.1.IoTCapability.2.LevelControl.MaxValue   = 25

    ProxiedDevice.1.IoTCapability.3.Class                   = &quot;LevelControl&quot;
    ProxiedDevice.1.IoTCapability.3.LevelControl.Type       = &quot;Temperature&quot;
    ProxiedDevice.1.IoTCapability.3.LevelControl.Description = &quot;TargetHeatTemperature&quot;
    ProxiedDevice.1.IoTCapability.3.LevelControl.Value      = 21
    ProxiedDevice.1.IoTCapability.3.LevelControl.Unit       = &quot;degC&quot;
    ProxiedDevice.1.IoTCapability.3.LevelControl.MinValue   = 14
    ProxiedDevice.1.IoTCapability.3.LevelControl.MaxValue   = 25

    ProxiedDevice.1.IoTCapability.4.Class                   = &quot;LevelControl&quot;
    ProxiedDevice.1.IoTCapability.4.LevelControl.Type       = &quot;Temperature&quot;
    ProxiedDevice.1.IoTCapability.4.LevelControl.Description = &quot;TargetEnergyCoolTemp&quot;
    ProxiedDevice.1.IoTCapability.4.LevelControl.Value      = 19
    ProxiedDevice.1.IoTCapability.4.LevelControl.Unit       = &quot;degC&quot;
    ProxiedDevice.1.IoTCapability.4.LevelControl.MinValue   = 14
    ProxiedDevice.1.IoTCapability.4.LevelControl.MaxValue   = 25

    ProxiedDevice.1.IoTCapability.5.Class                   = &quot;LevelControl&quot;
    ProxiedDevice.1.IoTCapability.5.LevelControl.Type       = &quot;Temperature&quot;
    ProxiedDevice.1.IoTCapability.5.LevelControl.Description = &quot;TargetEnergyHeatTemp&quot;
    ProxiedDevice.1.IoTCapability.5.LevelControl.Value      = 19
    ProxiedDevice.1.IoTCapability.5.LevelControl.Unit       = &quot;degC&quot;
    ProxiedDevice.1.IoTCapability.5.LevelControl.MinValue   = 14
    ProxiedDevice.1.IoTCapability.5.LevelControl.MaxValue   = 25

    ProxiedDevice.1.IoTCapability.6.Class                   = &quot;LevelSensor&quot;
    ProxiedDevice.1.IoTCapability.6.LevelSensor.Type        = &quot;Temperature&quot;
    ProxiedDevice.1.IoTCapability.6.LevelSensor.Value       = 19.5
    ProxiedDevice.1.IoTCapability.6.LevelSensor.Unit        = &quot;degC&quot;

    ProxiedDevice.1.IoTCapability.7.Class                   = &quot;EnumControl&quot;
    ProxiedDevice.1.IoTCapability.7.EnumControl.Type        = &quot;FanMode&quot;
    ProxiedDevice.1.IoTCapability.7.EnumControl.Value       = &quot;Low&quot;
    ProxiedDevice.1.IoTCapability.7.EnumControl.ValidValues = &quot;Auto_low, Low,
                                                              Circulation, Off&quot;

    ProxiedDevice.1.IoTCapability.8.Class                   = &quot;EnumSensor&quot;
    ProxiedDevice.1.IoTCapability.8.EnumSensor.Type         = &quot;OperatingState&quot;
    ProxiedDevice.1.IoTCapability.8.EnumSensor.Value        = &quot;Cooling&quot;
    ProxiedDevice.1.IoTCapability.8.EnumSensor.ValidValues  =
                &quot;Heating, Cooling,
                FanOnly, PendingHeat, PendingCool, VentEconomizer,
                AuxHeating, 2ndStageHeating, 2ndStageCooling,
                2ndStageAuxHeat, 3rdStageAuxHeat&quot;</code></pre>
<h3 class="appendix3 auto-hoverlink" data-info="header"
id="sec:example-light-with-a-dimmer-and-switch">V.5.2 Example: Light
with a dimmer and switch</h3>
<p>This example shows a dimmable light connected over Z-Wave as proxied
device to an IoT Gateway.</p>
<p>Structure elements:</p>
<ul>
<li>IoTCapability.1 (BinaryControl) : On/Off Switch, expressed as
<code>true</code> and <code>false</code> value</li>
<li>IoTCapability.2 (LevelControl) : Brightness control from 0% to
100%</li>
</ul>
<p>Instantiated data model:</p>
<pre><code>    ProxiedDevice.2.Type                                      = &quot;Light&quot;
    ProxiedDevice.2.Online                                    = &quot;true&quot;
    ProxiedDevice.2.ProxyProtocol                             = &quot;Z-Wave&quot;
    ProxiedDevice.2.Name                                      = &quot;GE DimMing Bulb&quot;
    ProxiedDevice.2.IoTCapabilityNumberOfEntries              = 2

    ProxiedDevice.2.IoTCapability.1.Class                     = &quot;BinaryControl&quot;
    ProxiedDevice.2.IoTCapability.1.BinaryControl.Type        = &quot;Switch&quot;
    ProxiedDevice.2.IoTCapability.1.BinaryControl.Value       = true

    ProxiedDevice.2.IoTCapability.2.Class                     = &quot;LevelControl&quot;
    ProxiedDevice.2.IoTCapability.2.LevelControl.Type         = &quot;Brightness&quot;
    ProxiedDevice.2.IoTCapability.2.LevelControl.Value        = 100
    ProxiedDevice.2.IoTCapability.2.LevelControl.Min          = 0
    ProxiedDevice.2.IoTCapability.2.LevelControl.Max          = 100
    ProxiedDevice.2.IoTCapability.2.LevelControl.Unit         = &quot;%&quot;</code></pre>
<h3 class="appendix3 auto-hoverlink" data-info="header"
id="sec:example-fan">V.5.3 Example: Fan</h3>
<p>This example shows a simple fan connected over Z-Wave as proxied
device to an IoT Gateway.</p>
<p>Structure elements:</p>
<ul>
<li>IoTCapability.1 (EnumControl) : Fan state</li>
</ul>
<p>Instantiated data model:</p>
<pre><code>    ProxiedDevice.3.Type                                       = &quot;Fan&quot;
    ProxiedDevice.3.Online                                     = &quot;true&quot;
    ProxiedDevice.3.ProxyProtocol                              = &quot;Z-Wave&quot;
    ProxiedDevice.3.name                                       = &quot;GE Fan&quot;
    ProxiedDevice.3.IoTCapabilityNumberOfEntries               = 1

    ProxiedDevice.2.IoTCapability.1.Class                      = &quot;EnumControl&quot;
    ProxiedDevice.3.IoTCapability.1.EnumControl.Type           = &quot;FanMode&quot;
    ProxiedDevice.3.IoTCapability.1.EnumControl.Value          = &quot;Off&quot;
    ProxiedDevice.3.IoTCapability.1.EnumControlValidValues     =
                            &quot;Off, Low, Medium, High, On, Auto, Smart&quot;</code></pre>
<h3 class="appendix3 auto-hoverlink" data-info="header"
id="example-multi-sensor-strip-with-a-common-battery">V.5.4 Example:
Multi-Sensor strip with a common battery.</h3>
<p>The sensors are inserted into the strip and may have their own power
switch, battery, energy consumption and manufacturer.</p>
<p>Instantiated data model:</p>
<pre><code>    ProxiedDevice.4.Type                                             = &quot;SensorStrip&quot;
    ProxiedDevice.4.Online                                           = true
    ProxiedDevice.4.ProxyProtocol                                    = &quot;Z-Wave&quot;
    ProxiedDevice.4.Name                                             = &quot;Insertable Sensor Strip&quot;
    ProxiedDevice.4.IoTCapabilityNumberOfEntries                     = 1
    ProxiedDevice.4.NodeNumberOfEntries                              = 2

    ProxiedDevice.4.IoTCapability.1.Class                            = &quot;LevelSensor&quot;
    ProxiedDevice.4.IoTCapability.1.LevelSensor.Value                = 80
    ProxiedDevice.4.IoTCapability.1.LevelSensor.Unit                 = &quot;%&quot;
    ProxiedDevice.4.IoTCapability.1.LevelSensor.Type                 = &quot;Battery&quot;
    ProxiedDevice.4.IoTCapability.1.LevelSensor.LowLevelThreshold    = 30
    ProxiedDevice.4.IoTCapability.1.LevelSensor.LowLevel             = false

    ProxiedDevice.4.Node.1.Type                                      = &quot;Sensor&quot;
    ProxiedDevice.4.Node.1.IoTCapabilityNumberOfEntries              = 1

    ProxiedDevice.4.Node.1.IoTCapability.1.Class                     = &quot;BinarySensor&quot;
    ProxiedDevice.4.Node.1.IoTCapability.1.BinarySensor.HoldTime     = 0
    ProxiedDevice.4.Node.1.IoTCapability.1.BinarySensor.Sensitivity  = 5
    ProxiedDevice.4.Node.1.IoTCapability.1.BinarySensor.RestTime     = 10000
    ProxiedDevice.4.Node.1.IoTCapability.1.BinarySensor.Value        = false
    ProxiedDevice.4.Node.1.IoTCapability.1.BinarySensor.Type         = &quot;MotionDetected&quot;
    ProxiedDevice.4.Node.1.IoTCapability.1.BinarySensor.LastSensingTime  = 1573344000</code></pre>
<h3 class="appendix3 auto-hoverlink" data-info="header"
id="sec:example-ceiling-fan-with-integrated-light">V.5.5 Example:
Ceiling Fan with integrated light</h3>
<p>This example shows a ceiling fan with integrated light connected over
Z-Wave as proxied device to an IoT Gateway.</p>
<p>Structure elements:</p>
<ul>
<li>IoTCapability.1 (BinaryControl) :</li>
<li>Node.1 : Represents the light control</li>
<li>.IoTCapability.1 (LevelControl) : Brightness control from 0% to
100%</li>
<li>.IoTCapability.2 (BinaryControl) : On/Off Switch, expressed as
<code>true</code> and <code>false</code> value</li>
<li>Node.2 : Fan control</li>
<li>.IoTCapability.1 (EnumControl) : Set fan state</li>
</ul>
<p>Instantiated data model:</p>
<pre><code>    ProxiedDevice.5.Type                                           = &quot;Fan&quot;
    ProxiedDevice.5.Online                                         = true
    ProxiedDevice.5.ProxyProtocol                                  = &quot;Z-Wave&quot;
    ProxiedDevice.5.Name                                           = &quot;42&#39;&#39; Ceiling Fan&quot;

    ProxiedDevice.5.IoTCapabilityNumberOfEntries                   = 1
    ProxiedDevice.5.NodeNumberOfEntries                            = 2

    ProxiedDevice.5.IoTCapability.1.Class                          = &quot;BinaryControl&quot;
    ProxiedDevice.5.IoTCapability.1.BinaryControl.Type             = &quot;Switch&quot;
    ProxiedDevice.5.IoTCapability.1.BinaryControl.State            = true

    ProxiedDevice.5.Node.1.Type                                    = &quot;Light&quot;
    ProxiedDevice.5.Node.1.IoTCapabilityNumberOfEntries            = 2

    ProxiedDevice.5.Node.1.IoTCapability.1.Class                   = &quot;LevelControl&quot;
    ProxiedDevice.5.Node.1.IoTCapability.1.LevelControl.Type       = &quot;Brightness&quot;
    ProxiedDevice.5.Node.1.IoTCapability.1.LevelControl.Value      = 99
    ProxiedDevice.5.Node.1.IoTCapability.1.LevelControl.MinValue   = 0
    ProxiedDevice.5.Node.1.IoTCapability.1.LevelControl.MaxValue   = 100
    ProxiedDevice.5.Node.1.IoTCapability.1.LevelControl.Unit       = &quot;%&quot;

    ProxiedDevice.5.Node.1.IoTCapability.2.Class                   = &quot;BinaryControl&quot;
    ProxiedDevice.5.Node.1.IoTCapability.2.BinaryControl.Type      = &quot;Switch&quot;
    ProxiedDevice.5.Node.1.IoTCapability.2.BinaryControl.Value     = true

    ProxiedDevice.5.Node.2.Type                                    = &quot;Fan&quot;
    ProxiedDevice.5.Node.2.IoTCapabilityNumberOfEntries            = 1

    ProxiedDevice.5.Node.2.IoTCapability.1.Class                   = &quot;EnumControl&quot;
    ProxiedDevice.5.Node.2.IoTCapability.1.EnumControl.Type        = &quot;FanMode&quot;
    ProxiedDevice.5.Node.2.IoTCapability.1.EnumControl.Value       = &quot;Off&quot;
    ProxiedDevice.5.Node.2.IoTCapability.1.EnumControl.ValidValues = &quot;Off, Low,
                                                                  Medium, High,
                                                                  Auto, Smart</code></pre>
<h3 class="appendix3 auto-hoverlink" data-info="header"
id="sec:example-power-strip">V.5.6 Example: Power strip</h3>
<p>This example shows a power strip with integrated power measurements
connected over Z-Wave as proxied device to an IoT Gateway.</p>
<p>Structure elements:</p>
<ul>
<li>IoTCapability.1 (BinaryControl) : On/Off Switch for complete power
strip</li>
<li>IoTCapability.2 (LevelSensor) : Total power reading of strip in
KWh.</li>
<li>Node.1 - 3: Each node represents a power outlet with:
<ul>
<li>.IoTCapability.1 (BinaryControl) : On/Off Switch, expressed as
<code>true</code> and <code>false</code> value</li>
<li>.IoTCapability.2 (LevelSensor) : Current power reading of outlet in
Watt.</li>
<li>.IoTCapability.3 (LevelSensor) : Total used power reading of outlet
in KWh.</li>
</ul></li>
</ul>
<p>Instantiated data model:</p>
<pre><code>    ProxiedDevice.6.Type                                         = &quot;PowerStrip&quot;
    ProxiedDevice.6.Online                                       = &quot;true&quot;
    ProxiedDevice.6.ProxyProtocol                                = &quot;Z-Wave&quot;
    ProxiedDevice.6.Name                                         = &quot;3 Plug Strip&quot;
    ProxiedDevice.6.IoTCapabilityNumberOfEntries                 = 2
    ProxiedDevice.6.NodeNumberOfEntries                          = 3

    ProxiedDevice.6.IoTCapability.1.Class                        = &quot;BinaryControl&quot;
    ProxiedDevice.6.IoTCapability.1.BinaryControl.Type           = &quot;Switch&quot;
    ProxiedDevice.6.IoTCapability.1.BinaryControl.Value          = true
    ProxiedDevice.6.IoTCapability.3.Class                        = &quot;LevelSensor&quot;
    ProxiedDevice.6.IoTCapability.3 Name                         = &quot;Total Accumulated Power&quot;
    ProxiedDevice.6.IoTCapability.3.LevelSensor.Type             = &quot;Power&quot;
    ProxiedDevice.6.IoTCapability.3.LevelSensor.Unit             = &quot;KWh&quot;
    ProxiedDevice.6.IoTCapability.3.LevelSensor.Value            = &quot;2227,56&quot;

    ProxiedDevice.6.Node.1.Type                                  = &quot;Switch&quot;
    ProxiedDevice.6.Node.1.IoTCapabilityNumberOfEntries          = 3
    ProxiedDevice.6.Node.1.IoTCapability.1.Class                 = &quot;BinaryControl&quot;
    ProxiedDevice.6.Node.1.IoTCapability.1.BinaryControl.Type    = &quot;Switch&quot;
    ProxiedDevice.6.Node.1.IoTCapability.1.BinaryControl.State   = true
    ProxiedDevice.6.Node.1.IoTCapability.2.Class                 = &quot;LevelSensor&quot;
    ProxiedDevice.6.Node.1.IoTCapability.2.LevelSensor.Type      = &quot;Power&quot;
    ProxiedDevice.6.Node.1.IoTCapability.2.LevelSensor.Unit      = &quot;W&quot;
    ProxiedDevice.6.Node.1.IoTCapability.2.LevelSensor.Value     = 99
    ProxiedDevice.6.Node.1.IoTCapability.3.Class                 = &quot;LevelSensor&quot;
    ProxiedDevice.6.Node.1.IoTCapability.3 Name                  = &quot;Accumulated Power&quot;
    ProxiedDevice.6.Node.1.IoTCapability.3.LevelSensor.Type      = &quot;Power&quot;
    ProxiedDevice.6.Node.1.IoTCapability.3.LevelSensor.Unit      = &quot;KWh&quot;
    ProxiedDevice.6.Node.1.IoTCapability.3.LevelSensor.Value     = 390.67

    ProxiedDevice.6.Node.2.Type                                  = &quot;Switch&quot;
    ProxiedDevice.6.Node.2.IoTCapabilityNumberOfEntries          = 3
    ProxiedDevice.6.Node.2.IoTCapability.1.Class                 = &quot;BinaryControl&quot;
    ProxiedDevice.6.Node.2.IoTCapability.1.BinaryControl.Type    = &quot;Switch&quot;
    ProxiedDevice.6.Node.2.IoTCapability.1.BinaryControl.State   = true
    ProxiedDevice.6.Node.2.IoTCapability.2.Class                 = &quot;LevelSensor&quot;
    ProxiedDevice.6.Node.2.IoTCapability.2.LevelSensor.Type      = &quot;Power&quot;
    ProxiedDevice.6.Node.2.IoTCapability.2.LevelSensor.Unit      = &quot;W&quot;
    ProxiedDevice.6.Node.2.IoTCapability.2.LevelSensor.Value     = 76
    ProxiedDevice.6.Node.2.IoTCapability.3.Class                 = &quot;LevelSensor&quot;
    ProxiedDevice.6.Node.2.IoTCapability.3 Name                  = &quot;Accumulated Power&quot;
    ProxiedDevice.6.Node.2.IoTCapability.3.LevelSensor.Type      = &quot;Power&quot;
    ProxiedDevice.6.Node.2.IoTCapability.3.LevelSensor.Unit      = &quot;KWh&quot;
    ProxiedDevice.6.Node.2.IoTCapability.3.LevelSensor.Value     = 1783.63

    ProxiedDevice.6.Node.3.Type                                  = &quot;Switch&quot;
    ProxiedDevice.6.Node.3.IoTCapabilityNumberOfEntries          = 3
    ProxiedDevice.6.Node.3.IoTCapability.1.Class                 = &quot;BinaryControl&quot;
    ProxiedDevice.6.Node.3.IoTCapability.1.BinaryControl.Type    = &quot;Switch&quot;
    ProxiedDevice.6.Node.3.IoTCapability.1.BinaryControl.State   = true
    ProxiedDevice.6.Node.3.IoTCapability.2.Class                 = &quot;LevelSensor&quot;
    ProxiedDevice.6.Node.3.IoTCapability.2.LevelSensor.Type      = &quot;Power&quot;
    ProxiedDevice.6.Node.3.IoTCapability.2.LevelSensor.Unit      = &quot;W&quot;
    ProxiedDevice.6.Node.3.IoTCapability.2.LevelSensor.Value     = 0
    ProxiedDevice.6.Node.3.IoTCapability.3.Class                 = &quot;LevelSensor&quot;
    ProxiedDevice.6.Node.3.IoTCapability.3 Name                  = &quot;Accumulated Power&quot;
    ProxiedDevice.6.Node.3.IoTCapability.3.LevelSensor.Type      = &quot;Power&quot;
    ProxiedDevice.6.Node.3.IoTCapability.3.LevelSensor.Unit      = &quot;KWh&quot;
    ProxiedDevice.6.Node.3.IoTCapability.3.LevelSensor.Value     = 53.26</code></pre>
<h3 class="appendix3 auto-hoverlink" data-info="header"
id="sec:example-battery-powered-radiator-thermostat">V.5.7 Example:
Battery powered radiator thermostat</h3>
<p>This example shows the IoT model for a radiator thermostat with an
integrated USP Agent, which is directly controlled.</p>
<p>Structure elements:</p>
<ul>
<li>IoTCapability.1 (EnumControl): Operation Mode</li>
<li>IoTCapability.2 (EnumControl): Auto/Manual Temperature setting</li>
<li>IoTCapability.3 (EnumControl): Vacation Temperature setting</li>
<li>IoTCapability.4 (LevelSensor) : Current Temperature</li>
<li>IoTCapability.5 (LevelSensor): Valve position</li>
<li>IoTCapability.6 (LevelSensor): Battery status</li>
</ul>
<p><em>Note: All temperature settings are modeled as “EnumControl” to
define a range between 4 and 23° degC in steps of 0.5° or an “Off”
value.</em></p>
<p>Instantiated data model:</p>
<pre><code>    Device.DeviceInfo.Description                  = &quot;Battery powered radiator
                                                      thermostat&quot;

    Device.IoTCapabilityNumberOfEntries            = 6

    Device.IoTCapability.1.Class                   = &quot;EnumControl
    Device.IoTCapability.1.EnumControl.Type        = &quot;ThermostatMode&quot;
    Device.IoTCapability.1.EnumControl.ValidValues = &quot;Off, Auto, Manual, Vacation&quot;
    Device.IoTCapability.1.EnumControl.Value       = &quot;Auto&quot;      # current mode

    Device.IoTCapability.2.Class                   = &quot;EnumControl
    Device.IoTCapability.2.Name                    = &quot;Desired Temperature&quot;
    Device.IoTCapability.2.EnumControl.Type        = &quot;TemperatureMode&quot;
    Device.IoTCapability.2.EnumControl.ValidValues = &quot;Off, 4, 4.5, 5.0, 5.5,
                                                     6, 6.5, 7, 7.5, 8, 8.5,
                                                     9, 9.5, 10, 10.5, 11,
                                                     11.5, 12, 12.5, 13, 13.5,
                                                     14, 14.5, 15.0, 15.5, 16,
                                                     16.5, 17, 17.5, 18, 18.5,
                                                     19, 19.5, 20, 20.5, 21,
                                                     21.5, 22, 22.5, 23&quot;
    Device.IoTCapability.2.EnumControl.Value       = 19   # Requested temperature

    Device.IoTCapability.3.Class                   = &quot;EnumControl&quot;
    Device.IoTCapability.3.Name                    = &quot;Vacation Temperature&quot;
    Device.IoTCapability.3.EnumControl.Type        = &quot;TemperatureMode&quot;
    Device.IoTCapability.3.EnumControl.ValidValues = &quot;Off, 4, 4.5, 5.0, 5.5,
                                                     6, 6.5, 7, 7.5, 8, 8.5,
                                                     9, 9.5, 10, 10.5, 11,
                                                     11.5, 12, 12.5, 13, 13.5,
                                                     14, 14.5, 15.0, 15.5, 16,
                                                     16.5, 17, 17.5, 18, 18.5,
                                                     19, 19.5, 20, 20.5, 21,
                                                     21.5, 22, 22.5, 23&quot;
    Device.IoTCapability.3.EnumControl.Value       = 12   # Requested temperature
                                                            # during absence

    Device.IoTCapability.4.Class                   = &quot;LevelSensor&quot;
    Device.IoTCapability.4.Name                    = &quot;Current Temperature&quot;
    Device.IoTCapability.4.LevelSensor.Type        = &quot;Temperature&quot;
    Device.IoTCapability.4.LevelSensor.Unit        = &quot;degC&quot;
    Device.IoTCapability.4.LevelSensor.Value       = 19.3 # Current temperature

    Device.IoTCapability.5.Class                   = &quot;LevelSensor&quot;
    Device.IoTCapability.5.Name                    = &quot;Valve Position&quot;
    Device.IoTCapability.5.LevelSensor.Type        = &quot;Position&quot;
    Device.IoTCapability.5.LevelSensor.Unit        = &quot;%&quot;
    Device.IoTCapability.5.LevelSensor.MinValue    = 0
    Device.IoTCapability.5.LevelSensor.MaxValue    = 100
    Device.IoTCapability.5.LevelSensor.Value       = 16     # e.g. 16% valve
                                                               # opening

    Device.IoTCapability.6.Class                   = &quot;LevelSensor&quot;
    Device.IoTCapability.6.Name                    = &quot;Local Battery&quot;
    Device.IoTCapability.6.LevelSensor.Type        = &quot;Battery&quot;
    Device.IoTCapability.6.LevelSensor.Unit        = &quot;%&quot;
    Device.IoTCapability.6.LevelSensor.MinValue    = 0
    Device.IoTCapability.6.LevelSensor.MaxValue    = 100
    Device.IoTCapability.6.LevelSensor.Value       = 82      # e.g. 82% battery load</code></pre>
<h1 class="appendix1 auto-hoverlink" data-info="header"
id="sec:software-modularization-theory-of-operations">Appendix VI:
Software Modularization and USP-Enabled Applications Theory of
Operation</h1>
<p>This section discusses the Theory of Operation for Software
Modularization and USP-Enabled Applications within Connected
Devices.</p>
<h2 class="appendix2 auto-hoverlink" data-info="header"
id="sec:background">VI.1 Background</h2>
<p>Operators and manufacturers of connected devices are moving away from
monolithic firmware images and toward a more modular approach to
firmware architecture. The reasons for this trend are mostly related to
the ability to more quickly adapt to subscriber demands. By moving to a
more modularized software stack on the connected device, Operators are
able to reduce the current device firmware versioning lead times
(typically 12 to 18 months) and introduce new services at a much faster
pace. To aid in this evolution, there needs to be a standard mechanism
to install/update/uninstall software modules (see <a
href="#sec:software-module-management" class="heading">Software Module
Management appendix</a>) and there needs to be a standard communications
mechanism that allows the services to expose their own data model to
both internal components and remote management entities as well as
consume other portions of the device’s data model (the purpose of this
Appendix). A side-effect of this software modularization is that certain
individual services can also be updated independently of the overall
firmware, which helps in both enhancing already enabled services and
performing quick patches to address any security issues.</p>
<h2 class="appendix2 auto-hoverlink" data-info="header"
id="sec:basic-solution-concepts">VI.2 Basic Solution Concepts</h2>
<p>The following concepts are key components of the overall solution to
enable connected device software modularization by deploying USP-enabled
applications.</p>
<ul>
<li>USP Broker:
<ul>
<li><strong>An entity that is responsible for exposing a consolidated
set of Service Elements for the device to external USP Controllers. This
includes any data model elements exposed by the USP Agent contained
within the USP Broker as well as any data model elements exposed by USP
Services that have connected to the USP Broker. Furthermore, the USP
Broker serves as an intermediary for USP Services looking to interact
with data model elements that are maintained by other portions of the
device (the USP Broker or other USP Services).</strong></li>
<li>A USP Broker has both a USP Agent and a USP Controller embedded in
it.</li>
<li>The USP Agent serves as both the Agent that exposes the device’s
management environment to the external world and the Agent to any USP
Controllers that reside inside the device.</li>
<li>The USP Controller serves as the Controller for all communications
with USP services.</li>
<li>For a USP Broker to recognize a USP Agent as a USP Service, it needs
to register a portion of its data model via the Register message.</li>
</ul></li>
<li>USP Service:
<ul>
<li><strong>An entity that is responsible for implementing a portion of
the device’s overall functionality. A USP Service exposes a set of
Service Elements related to the functionality that it is responsible for
implementing. A USP Service could have a need to interact with Service
Elements that are outside of its functional domain, whether that be
Service Elements exposed by the USP Broker or some other USP
Service.</strong></li>
<li>A USP Service has a USP Agent and could have a USP Controller
embedded in it.</li>
<li>The USP Agent serves to expose the portion of the data model that is
controlled by the USP Service to the USP Broker. (data model
provider).</li>
<li>The USP Controller serves to retrieve/configure portions of the data
model that are not directly exposed by the USP Service. (data model
consumer).</li>
<li>If a USP Service has both a USP Agent and a USP Controller then it
is highly recommended that they both use the same Endpoint ID.
<ul>
<li>If the USP Agent and USP Controller don’t use the same Endpoint ID
then the USP Broker won’t be able to correlate the two USP Endpoints as
a single USP Service.</li>
</ul></li>
<li>Based on use cases (see below) not all USP Services will need a USP
Controller.</li>
</ul></li>
<li>UNIX Domain Socket MTP:
<ul>
<li><strong>An internal MTP for communications within the device via
UNIX Domain Sockets.</strong></li>
<li>The USP Broker will maintain a well-known UNIX Domain Socket
facilitating an easy place for Controllers within USP Services to
connect.</li>
<li>The USP Broker will maintain a well-known UNIX Domain Socket
facilitating an easy place for Agents within USP Services to
connect.</li>
<li>TLVs are used to encapsulate any headers (e.g. identification,
length of full message) and the USP Record itself in protobuf form.</li>
<li>No authentication is needed as the installation of the software
module itself will essentially grant access (assumption that you should
only install trusted applications).
<ul>
<li>This can be enhanced in later versions.</li>
</ul></li>
</ul></li>
</ul>
<h2 class="appendix2 auto-hoverlink" data-info="header"
id="sec:usp-service-use-cases">VI.3 USP Service Use Cases</h2>
<p>The following 3 use cases represent 3 unique types of USP
Services.</p>
<ol type="1">
<li>Data Model Provider Application
<ol type="1">
<li><strong>Description:</strong> USP Service that exposes a data
model</li>
<li><strong>Example:</strong> A Software Module that implements a Speed
Test</li>
<li><strong>Components:</strong>
<ol type="1">
<li>USP Agent (data model provider)</li>
</ol></li>
</ol></li>
<li>Integrated Data Model Application
<ol type="1">
<li><strong>Description:</strong> USP Service that both exposes a data
model and needs to interact with dependent portions of the data model
being exposed by other entities</li>
<li><strong>Example:</strong> A Software Module that implements a
Network Topology View</li>
<li><strong>Components:</strong>
<ol type="1">
<li>USP Agent (data model provider)</li>
<li>USP Controller (data model consumer)</li>
</ol></li>
</ol></li>
<li>Cloud Application
<ol type="1">
<li><strong>Description:</strong> USP Service that resides in the
cloud</li>
<li><strong>Example:</strong> A Software Module that implements a
cloud-based Wi-Fi mesh controller</li>
<li><strong>Components:</strong> Could be any Agent/Controller
combination as described in use case 1 or 2</li>
</ol></li>
</ol>
<p>The following image depicts the first 2 use cases where the USP
Service number corresponds to the use case number (i.e., USP Service 1
is a reflection of use case 1).</p>
<figure id="fig:software-modularization-use-cases">
<img src="extensions/device-modularization/./use-cases.png"
id="img:software-modularization-use-cases"
alt="Software Modularization Use Cases" />
<figcaption><div class="auto-hoverlink"
data-anchor="fig:software-modularization-use-cases">
Figure 39: Software Modularization Use Cases
</div></figcaption>
</figure>
<h2 class="appendix2 auto-hoverlink" data-info="header"
id="sec:usp-broker-responsibilities">VI.4 USP Broker
Responsibilities</h2>
<p>A USP Broker generally has 3 main responsibilities:</p>
<ul>
<li>Track the Service Elements (portions of the data model) that the USP
Services wish to expose to other entities.</li>
<li>Proxy USP communications internally within the device based on the
Service Elements that the USP Services have exposed.</li>
<li>Provide a consolidated view of the device’s Service Elements to USP
Controllers that reside externally to the device.</li>
</ul>
<p>When a USP Service is started, there will be a data model
registration to inform the USP Broker which Service Elements (portions
of the data model) should be exposed for this USP Service. This means
that one of the key responsibilities of the USP Broker is to track the
portion of the data model associated with each USP Service, which is
facilitated by receiving a Register USP message from the USP Agent of
the USP Service.</p>
<p>The USP Agent portion of the USP Broker provides a consolidated view
of the device’s Service Elements (including all Service Elements exposed
by USP Services) to USP Controllers that are external to the device, and
those USP Controllers will send USP messages to the device that require
the USP Broker to proxy either the entire USP message or a portion of
the USP message to one or more USP Services based on the Service
Elements being exposed by the various USP Services. These USP messages
can come in many forms:</p>
<ul>
<li>A Get message to retrieve various portions of the data model that
could be distributed across multiple USP Services.</li>
<li>A Set message to configure various portions of the data model that
could be distributed across multiple USP Services.</li>
<li>An Add message to create and configure a new instance of a data
model object, and while each data model object is only served by a
single USP Service, the Add message could be creating instances of
multiple data model objects that could be distributed across multiple
USP Services.</li>
<li>A Delete message to remove an existing instance of a data model
object, and while each data model object is only served by a single USP
Service, the Delete message could be removing instances from multiple
data model objects that could be distributed across multiple USP
Services.</li>
<li>An Operate message to execute a data model command, which would be
handled by a single USP Service.</li>
</ul>
<p>The USP Agent portion of the USP Broker might also need to handle
notifications and subscriptions. These subscriptions might be created by
either USP Controllers that are external to the device or USP Services
that are internal to the device, where they are looking for
notifications related to a part of the device’s Service Elements where
some portions of that subscription could be distributed across multiple
USP Services. This means that the USP Agent portion of the USP Broker
might need to send USP Notify messages to external USP Controllers or
internal USP Controllers associated with USP Services that have created
associated Subscriptions.</p>
<h2 class="appendix2 auto-hoverlink" data-info="header"
id="sec:data-model-implications-for-usp-brokers-and-usp-services">VI.5
Data Model Implications for USP Brokers and USP Services</h2>
<h3 class="appendix3 auto-hoverlink" data-info="header"
id="sec:unix-domain-socket-data-model-table-and-the-uds-mtp-objects">VI.5.1
UNIX Domain Socket Data Model Table and the UDS MTP Objects</h3>
<p>The MTP table of the LocalAgent object represents the Message
Transfer Protocols (MTPs) that a USP Agent is currently using. So an MTP
instance with a Protocol of UNIX Domain Socket means that the USP Broker
or USP Service has an Agent that is configured to use the UNIX Domain
Socket MTP for communications within the device between the USP Broker
and one or more USP Services.</p>
<p>Each instance of the LocalAgent.Controller table represents a USP
Controller that has access to the associated USP Agent. For a USP
Service that would be the USP Broker’s Controller, which means that a
USP Service will only have 1 instance of the LocalAgent.Controller table
and the UDS MTP object will contain a Reference to the UnixDomainSocket
Object instance containing the Path to the Controller portion of the USP
Broker and be in a Connect Mode. For a USP Broker that would be the USP
Service’s Controller (if it exists), which means that a USP Broker will
have an instance of the LocalAgent.Controller table for each USP Service
that contains a Controller. Each LocalAgent.Controller instance would
have a UDS MTP object that contains a reference to the USPService Object
instance containing details about the USP Service itself.</p>
<p>The LocalAgent.MTP.UDS instance will be auto-created based on the USP
Broker or USP Service supporting the UNIX Domain Socket MTP. The
LocalAgent.Controller instances for a USP Broker and USP Services will
be automatically created with the UDS instance based on USP Service
startup procedures. Given that and the USP Broker has well-known paths
for the Agent and Controller UNIX Domain Socket MTP, the UDS objects are
read-only.</p>
<p>Due to the lack of a discovery mechanism and to ensure a
interoperable environment where 3rd party USP Services can communicate
with the USP Broker, it is highly recommended that the USP Broker’s UNIX
Domain Socket paths used for both its USP Agent and USP Controller be
preset as follows:</p>
<ul>
<li>USP Broker’s USP Agent: /var/run/usp/broker_agent_path</li>
<li>USP Broker’s USP Controller:
/var/run/usp/broker_controller_path</li>
</ul>
<h3 class="appendix3 auto-hoverlink" data-info="header"
id="sec:uspservice-data-model-table">VI.5.2 USPService Data Model
Table</h3>
<p>The USP Broker should keep track of all USP Services it has an active
connection to, which includes the following parameters:</p>
<ul>
<li><strong>EndpointID:</strong> the Endpoint ID of the USP Agent within
the USP Service</li>
<li><strong>DataModelPaths:</strong> a list of data model paths that
have been registered by the USP Service</li>
<li><strong>DeploymentUnitRef:</strong> a reference to the Software
Module Deployment Unit, if applicable</li>
<li><strong>HasController:</strong> a flag that indicates whether or not
the USP Service has an embedded USP Controller (NOTE: this can be
determined when the USP Service’s USP Controller connects to the USP
Broker’s USP Agent if it is using the same Endpoint ID as the USP
Service’s USP Agent)</li>
</ul>
<p>When a USP Service disconnects then the associated USPService table
instance is removed.</p>
<h3 class="appendix3 auto-hoverlink" data-info="header"
id="sec:example-data-models-for-a-usp-broker-and-usp-services">VI.5.3
Example Data Models for a USP Broker and USP Services</h3>
<p>Here’s an example set of data models for a USP Broker and 2 USP
Services that matches the use cases depicted in the Figure shown in the
previous section.</p>
<p>USP Broker (NOTE: there isn’t a Controller.1 instance because USP
Service 1 doesn’t have a Controller):</p>
<pre><code>UnixDomainSocket.1.Path = /var/run/usp/broker_agent_path
UnixDomainSocket.1.Mode = Listen
UnixDomainSocket.2.Path = /var/run/usp/broker_controller_path
UnixDomainSocket.2.Mode = Listen
LocalAgent.MTP.1.UDS.UnixDomainSocketRef = UnixDomainSocket.1
LocalAgent.Controller.2.MTP.1.UDS.UnixDomainSocketRef = UnixDomainSocket.1
LocalAgent.Controller.2.MTP.1.UDS.USPServiceRef = USPService.2
USPService.1.EndpointID = doc::Service1
USPService.1.DataModelPaths = PathA, PathB, PathC
USPService.1.DeploymentUnitRef = SoftwareModules.DeploymentUnit.1
USPService.1.HasController = false
USPService.2.EndpointID = doc::Service2
USPService.2.DataModelPaths = PathX, PathY, PathZ
USPService.2.DeploymentUnitRef = SoftwareModules.DeploymentUnit.2
USPService.2.HasController = true</code></pre>
<p>USP Service 1 (NOTE: USP Service 1 doesn’t have a Controller, so
there isn’t a Controller instance in the USP Broker for this USP
Service):</p>
<pre><code>UnixDomainSocket.2.Path = /var/run/usp/broker_controller_path
UnixDomainSocket.2.Mode = Connect
LocalAgent.MTP.1.UDS.UnixDomainSocketRef = UnixDomainSocket.2
LocalAgent.Controller.1.MTP.1.UDS.UnixDomainSocketRef = UnixDomainSocket.2
LocalAgent.Controller.1.MTP.1.UDS.USPServiceRef = &lt;empty&gt;</code></pre>
<p>USP Service 2 (has both an Agent and a Controller):</p>
<pre><code>UnixDomainSocket.1.Path = /var/run/usp/broker_agent_path
UnixDomainSocket.1.Mode = Connect
UnixDomainSocket.2.Path = /var/run/usp/broker_controller_path
UnixDomainSocket.2.Mode = Connect
LocalAgent.MTP.1.UDS.UnixDomainSocketRef = UnixDomainSocket.2
LocalAgent.Controller.1.MTP.1.UDS.UnixDomainSocketRef = UnixDomainSocket.2
LocalAgent.Controller.1.MTP.1.UDS.USPServiceRef = &lt;empty&gt;</code></pre>
<h2 class="appendix2 auto-hoverlink" data-info="header"
id="sec:startup-and-shutdown-procedures">VI.6 Startup and Shutdown
Procedures</h2>
<h3 class="appendix3 auto-hoverlink" data-info="header"
id="sec:device-boot-procedures">VI.6.1 Device Boot Procedures</h3>
<p>When the device boots up, the USP Broker comes online.  The USP
Broker exposes both a USP Agent (communicating externally and
internally; listening on a well-known internal path for communications
via the Unix Domain Socket MTP) and an internal USP Controller
(listening on a well-known internal path for communications via the Unix
Domain Socket MTP).  The USP Agent communicates externally via one or
more of the USP defined MTPs (MQTT, STOMP,  or WebSocket).  The USP
Agent also communicates internally via the Unix Domain Socket MTP and
begins to listen on a well-known internal path.  The USP Controller
communicates internally via the Unix Domain Socket MTP and begins to
listen on a well-known internal path.  Each installed and enabled USP
Service also starts up - see the next section.</p>
<h3 class="appendix3 auto-hoverlink" data-info="header"
id="sec:usp-service-startup-procedures">VI.6.2 USP Service Startup
Procedures</h3>
<p><em>Use Case 1 - Data Model Provider Application:</em></p>
<p>As the USP Service starts up, it begins to connect to the USP
Broker…</p>
<ul>
<li>The Agent within the USP Service initiates the UNIX Domain Socket
connection to the Controller on the USP Broker and the well-known
internal path
<ul>
<li>Once the UNIX Domain Socket is connected, the USP Service’s Agent
will initiate the UNIX Domain Socket MTP Handshake mechanism</li>
<li>Once the USP Broker’s Controller receives the UNIX Domain Socket MTP
Handshake message, it will respond with its own Handshake message</li>
<li>Once the UNIX Domain Socket MTP Handshake mechanism is successfully
completed, the Agent within the USP Service sends an empty
UnixDomainSocketConnectRecord</li>
<li>After sending the empty UnixDomainSocketConnectRecord, the Agent
within the USP Service sends a Register message to the Controller in the
USP Broker that details the portion of the data model that is being
exposed by the USP Service.</li>
</ul></li>
</ul>
<p><em>Use Case 2 - Integrated Data Model Application:</em></p>
<p>As the USP Service starts up, it begins to connect to the USP
Broker…</p>
<ul>
<li>The Agent within the USP Service initiates the UNIX Domain Socket
connection to the Controller on the USP Broker and the well-known
internal path
<ul>
<li>Once the UNIX Domain Socket is connected, the USP Service’s Agent
will initiate the UNIX Domain Socket MTP Handshake mechanism</li>
<li>Once the USP Broker’s Controller receives the UNIX Domain Socket MTP
Handshake message, it will respond with its own Handshake message</li>
<li>Once the UNIX Domain Socket MTP Handshake mechanism is successfully
completed, the Agent within the USP Service sends an empty
UnixDomainSocketConnectRecord</li>
<li>After sending the empty UnixDomainSocketConnectRecord, the Agent
within the USP Service sends a Register message to the Controller in the
USP Broker that details the portion of the data model that is being
exposed by the USP Service.</li>
</ul></li>
<li>The Controller within the USP Service initiates the UNIX Domain
Socket connection to the Agent on the USP Broker and the well-known
internal path
<ul>
<li>Once the UNIX Domain Socket is connected, the USP Service’s
Controller will initiate the UNIX Domain Socket MTP Handshake
mechanism</li>
<li>Once the USP Broker’s Agent receives the UNIX Domain Socket MTP
Handshake message, it will respond with its own Handshake message</li>
<li>Once the UNIX Domain Socket MTP Handshake mechanism is successfully
completed, the Agent within the USP Broker sends an empty
UnixDomainSocketConnectRecord</li>
<li>Once the USP Service identifies that it is connected to the USP
Broker, the USP Service’s Controller can issue a GSDM to retrieve
portions of the USP Broker’s supported data model that it might need to
interact with</li>
</ul></li>
</ul>
<p><em>Use Case 3 - Cloud Application:</em></p>
<p><strong>Note:</strong> One of the key tenets of USP was that multiple
MTPs were defined not for general preferences but because each of them
serves a different kind of use case.  So when we define a new use case
(like this one), it is certainly conceivable that some MTPs might not be
appropriate.  In this case, the WebSocket MTP is less appropriate,
because it would require 2 socket connections to a WebSocket server.</p>
<p>As the USP Service starts up, it begins to connect to the USP
Broker…</p>
<ul>
<li>The Cloud USP Service establishes a connection to the STOMP/MQTT
Broker based on the Agent’s data model (STOMP.Connection / MQTT.Client)
<ul>
<li>The Agent within the Cloud USP Service send a STOMP/MQTT Connect
Record to the Controller of the USP Broker</li>
<li>After sending the appropriate Connect Record, the Agent within the
USP Service sends a Register message to the Controller in the USP Broker
that details the portion of the data model that is being exposed by the
USP Service.</li>
</ul></li>
<li>The USP Broker establishes a connection to the STOMP/MQTT Broker
based on the Agent’s data model (STOMP.Connection / MQTT.Client)
<ul>
<li><strong>Note:</strong> The USP Controller will need to configure the
USP Broker to communicate with the Cloud USP Service by setting up the
associated MTP connection details.</li>
<li>The Agent within the USP Broker sends a STOMP/MQTT Connect Record to
the Controller of the Cloud USP Service
<ul>
<li><strong>Note:</strong> This looks just like any other external USP
Controller that is configured within the USP Broker’s Agent.</li>
</ul></li>
<li>Once the Controller within the Cloud USP Service receives the
appropriate Connect Record, the Cloud USP Service’s Controller can issue
a GSDM to retrieve portions of the USP Broker’s supported data model
that it might need to interact with</li>
</ul></li>
</ul>
<h3 class="appendix3 auto-hoverlink" data-info="header"
id="sec:usp-service-shutdown-procedures">VI.6.3 USP Service Shutdown
Procedures</h3>
<p>When a USP Service terminates (either gracefully by sending a
Disconnect Record or abruptly by closing the UNIX Domain Socket
connection), the USP Broker will remove the portion of the data model
that was being exposed for the given USP Service.</p>
<h2 class="appendix2 auto-hoverlink" data-info="header"
id="sec:usp-services-and-software-modules">VI.7 USP Services and
Software Modules</h2>
<p>USP Services have a rough correlation to Software Modules and the
Software Module Management concepts defined within USP.  This means that
the installation of a Software Module might cause a USP Service to come
into existence, and that the removal of a Software Module might cause a
USP Service to cease to exist.  That being said, not all Software
Modules will contain a USP Service and not all USP Services will be part
of a Software Module.</p>
<p>If the USP Service includes a Controller, its access to the data
model will be subject to the permissions described in <a
href="#sec:rbac" class="heading">Role Based Access Control (RBAC)</a>.
The Roles which the Service needs in order to function at all, and the
Roles which are not essential but would enable the Service to offer more
functionality, can be included in the <code>InstallDU()</code> command
using the <code>RequiredRoles</code> and <code>OptionalRoles</code>
arguments respectively; these arguments can also be included in the
<code>Update()</code> command if needed. The <code>AvailableRoles</code>
parameter of the Execution Environment into which the Service is being
installed lists the Roles which are available to Services according to
the security policy of the EE.</p>
<p>Note: Special care needs to be taken when processing requests to
create a new EE or to change the <code>AvailableRoles</code> of an
existing EE, for example to prevent a Controller from creating an EE
with Roles which it does not itself have and thereby enabling privilege
escalation.</p>
<p>Once the Controller has connected to the USP Broker, a reference to
the resulting instance of <code>LocalAgent.Controller</code> will be
exposed in parameter <code>InternalController</code> of the Deployment
Unit.</p>
<h3 class="appendix3 auto-hoverlink" data-info="header"
id="sec:installing-a-software-module">VI.7.1 Installing a Software
Module</h3>
<p>Installing a Software Module that contains a USP Service will cause
the USP Service to startup (see <a
href="#sec:usp-service-startup-procedures" class="heading">VI.6.2</a>)
once the Software Module is installed and running.</p>
<h3 class="appendix3 auto-hoverlink" data-info="header"
id="sec:updating-a-software-module">VI.7.2 Updating a Software
Module</h3>
<p>Updating a Software Module that contains a USP Service will cause the
USP Service to be stopped (see <a
href="#sec:usp-service-shutdown-procedures" class="heading">VI.6.3</a>)
and then restarted (see “USP Service Startup Procedures”) once the
Software Module is updated and running once again.</p>
<h3 class="appendix3 auto-hoverlink" data-info="header"
id="sec:deleting-a-software-module">VI.7.3 Deleting a Software
Module</h3>
<p>Deleting a Software Module that contains a USP Service will  cause
the USP  Service to be removed (see <a
href="#sec:usp-service-shutdown-procedures"
class="heading">VI.6.3</a>).</p>
<aside id="footnotes" class="footnotes footnotes-end-of-document"
role="doc-endnotes">
<hr />
<ol>
<li id="fn1"><p>This state machine diagram refers to the successful
transitions caused by the USP commands that change the DU state and does
not model the error cases.<a href="#fnref1" class="footnote-back"
role="doc-backlink">↩︎</a></p></li>
<li id="fn2"><p>This state machine diagram refers to the successful
transitions caused by the <code>SetRequestedState()</code> or the
<code>Restart()</code> command within the <code>ExecutionUnit</code>
table and does not model the error cases.<a href="#fnref2"
class="footnote-back" role="doc-backlink">↩︎</a></p></li>
</ol>
</aside>
</div>
</body>
</html>
